public Apply ( |
||
skeleton | ||
lastTime | float | |
time | float | |
firedEvents | ExposedList |
|
alpha | float | |
setupPose | bool | |
mixingOut | bool | |
return | void |
static void ParseRotateTimeline (Skeleton skeleton, RotateTimeline timeline, AnimationClip clip) { var boneData = skeleton.Data.Bones[timeline.BoneIndex]; var bone = skeleton.Bones[timeline.BoneIndex]; AnimationCurve curve = new AnimationCurve(); float endTime = timeline.Frames[(timeline.FrameCount * 2) - 2]; float currentTime = timeline.Frames[0]; List<Keyframe> keys = new List<Keyframe>(); float rotation = timeline.Frames[1] + boneData.Rotation; keys.Add(new Keyframe(timeline.Frames[0], rotation, 0, 0)); int listIndex = 1; int frameIndex = 1; int f = 2; float[] frames = timeline.Frames; skeleton.SetToSetupPose(); float lastTime = 0; float angle = rotation; while (currentTime < endTime) { int pIndex = listIndex - 1; float curveType = timeline.GetCurveType(frameIndex - 1); if (curveType == 0) { //linear Keyframe pk = keys[pIndex]; float time = frames[f]; rotation = frames[f + 1] + boneData.Rotation; angle += Mathf.DeltaAngle(angle, rotation); float r = angle; float rOut = (r - pk.value) / (time - pk.time); pk.outTangent = rOut; keys.Add(new Keyframe(time, r, rOut, 0)); keys[pIndex] = pk; currentTime = time; timeline.Apply(skeleton, lastTime, currentTime, null, 1); lastTime = time; listIndex++; } else if (curveType == 1) { //stepped Keyframe pk = keys[pIndex]; float time = frames[f]; rotation = frames[f + 1] + boneData.Rotation; angle += Mathf.DeltaAngle(angle, rotation); float r = angle; float rOut = float.PositiveInfinity; pk.outTangent = rOut; keys.Add(new Keyframe(time, r, rOut, 0)); keys[pIndex] = pk; currentTime = time; timeline.Apply(skeleton, lastTime, currentTime, null, 1); lastTime = time; listIndex++; } else if (curveType == 2) { //bezier Keyframe pk = keys[pIndex]; float time = frames[f]; timeline.Apply(skeleton, lastTime, currentTime, null, 1); skeleton.UpdateWorldTransform(); rotation = frames[f + 1] + boneData.Rotation; angle += Mathf.DeltaAngle(angle, rotation); float r = angle; int steps = Mathf.FloorToInt((time - pk.time) / bakeIncrement); for (int i = 1; i <= steps; i++) { currentTime += bakeIncrement; if (i == steps) currentTime = time; timeline.Apply(skeleton, lastTime, currentTime, null, 1); skeleton.UpdateWorldTransform(); pk = keys[listIndex - 1]; rotation = bone.Rotation; angle += Mathf.DeltaAngle(angle, rotation); r = angle; float rOut = (r - pk.value) / (currentTime - pk.time); pk.outTangent = rOut; keys.Add(new Keyframe(currentTime, r, rOut, 0)); keys[listIndex - 1] = pk; listIndex++; lastTime = currentTime; } } frameIndex++; f += 2; } curve = EnsureCurveKeyCount(new AnimationCurve(keys.ToArray())); string path = GetPath(boneData); string propertyName = "localEulerAnglesBaked"; EditorCurveBinding xBind = EditorCurveBinding.FloatCurve(path, typeof(Transform), propertyName + ".x"); AnimationUtility.SetEditorCurve(clip, xBind, new AnimationCurve()); EditorCurveBinding yBind = EditorCurveBinding.FloatCurve(path, typeof(Transform), propertyName + ".y"); AnimationUtility.SetEditorCurve(clip, yBind, new AnimationCurve()); EditorCurveBinding zBind = EditorCurveBinding.FloatCurve(path, typeof(Transform), propertyName + ".z"); AnimationUtility.SetEditorCurve(clip, zBind, curve); }
private static void ApplyRotateTimeline(RotateTimeline rotateTimeline, Skeleton skeleton, float time, float alpha, MixPose pose, float[] timelinesRotation, int i, bool firstFrame) { if (firstFrame) { timelinesRotation[i] = 0f; } if (alpha == 1f) { rotateTimeline.Apply(skeleton, 0f, time, null, 1f, pose, MixDirection.In); return; } Bone bone = skeleton.bones.Items[rotateTimeline.boneIndex]; float[] frames = rotateTimeline.frames; if (time < frames[0]) { if (pose == MixPose.Setup) { bone.rotation = bone.data.rotation; } return; } float num; if (time >= frames[frames.Length - 2]) { num = bone.data.rotation + frames[frames.Length + -1]; } else { int num2 = Animation.BinarySearch(frames, time, 2); float num3 = frames[num2 + -1]; float num4 = frames[num2]; float curvePercent = rotateTimeline.GetCurvePercent((num2 >> 1) - 1, 1f - (time - num4) / (frames[num2 + -2] - num4)); num = frames[num2 + 1] - num3; num -= (float)((16384 - (int)(16384.499999999996 - (double)(num / 360f))) * 360); num = num3 + num * curvePercent + bone.data.rotation; num -= (float)((16384 - (int)(16384.499999999996 - (double)(num / 360f))) * 360); } float num5 = (pose != 0) ? bone.rotation : bone.data.rotation; float num6 = num - num5; float num7; if (num6 == 0f) { num7 = timelinesRotation[i]; } else { num6 -= (float)((16384 - (int)(16384.499999999996 - (double)(num6 / 360f))) * 360); float num8; float value; if (firstFrame) { num8 = 0f; value = num6; } else { num8 = timelinesRotation[i]; value = timelinesRotation[i + 1]; } bool flag = num6 > 0f; bool flag2 = num8 >= 0f; if (Math.Sign(value) != Math.Sign(num6) && Math.Abs(value) <= 90f) { if (Math.Abs(num8) > 180f) { num8 += (float)(360 * Math.Sign(num8)); } flag2 = flag; } num7 = num6 + num8 - num8 % 360f; if (flag2 != flag) { num7 += (float)(360 * Math.Sign(num8)); } timelinesRotation[i] = num7; } timelinesRotation[i + 1] = num6; num5 += num7 * alpha; bone.rotation = num5 - (float)((16384 - (int)(16384.499999999996 - (double)(num5 / 360f))) * 360); }
static private void ApplyRotateTimeline(RotateTimeline rotateTimeline, Skeleton skeleton, float time, float alpha, bool setupPose, float[] timelinesRotation, int i, bool firstFrame) { if (firstFrame) { timelinesRotation[i] = 0; } if (alpha == 1) { rotateTimeline.Apply(skeleton, 0, time, null, 1, setupPose, false); return; } Bone bone = skeleton.bones.Items[rotateTimeline.boneIndex]; float[] frames = rotateTimeline.frames; if (time < frames[0]) { if (setupPose) { bone.rotation = bone.data.rotation; } return; } float r2; if (time >= frames[frames.Length - RotateTimeline.ENTRIES]) // Time is after last frame. { r2 = bone.data.rotation + frames[frames.Length + RotateTimeline.PREV_ROTATION]; } else { // Interpolate between the previous frame and the current frame. int frame = Animation.BinarySearch(frames, time, RotateTimeline.ENTRIES); float prevRotation = frames[frame + RotateTimeline.PREV_ROTATION]; float frameTime = frames[frame]; float percent = rotateTimeline.GetCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + RotateTimeline.PREV_TIME] - frameTime)); r2 = frames[frame + RotateTimeline.ROTATION] - prevRotation; r2 -= (16384 - (int)(16384.499999999996 - r2 / 360)) * 360; r2 = prevRotation + r2 * percent + bone.data.rotation; r2 -= (16384 - (int)(16384.499999999996 - r2 / 360)) * 360; } // Mix between rotations using the direction of the shortest route on the first frame while detecting crosses. float r1 = setupPose ? bone.data.rotation : bone.rotation; float total, diff = r2 - r1; if (diff == 0) { total = timelinesRotation[i]; } else { diff -= (16384 - (int)(16384.499999999996 - diff / 360)) * 360; float lastTotal, lastDiff; if (firstFrame) { lastTotal = 0; lastDiff = diff; } else { lastTotal = timelinesRotation[i]; // Angle and direction of mix, including loops. lastDiff = timelinesRotation[i + 1]; // Difference between bones. } bool current = diff > 0, dir = lastTotal >= 0; // Detect cross at 0 (not 180). if (Math.Sign(lastDiff) != Math.Sign(diff) && Math.Abs(lastDiff) <= 90) { // A cross after a 360 rotation is a loop. if (Math.Abs(lastTotal) > 180) { lastTotal += 360 * Math.Sign(lastTotal); } dir = current; } total = diff + lastTotal - lastTotal % 360; // Store loops as part of lastTotal. if (dir != current) { total += 360 * Math.Sign(lastTotal); } timelinesRotation[i] = total; } timelinesRotation[i + 1] = diff; r1 += total * alpha; bone.rotation = r1 - (16384 - (int)(16384.499999999996 - r1 / 360)) * 360; }
private static void ApplyRotateTimeline(RotateTimeline rotateTimeline, Skeleton skeleton, float time, float alpha, MixPose pose, float[] timelinesRotation, int i, bool firstFrame) { if (firstFrame) { timelinesRotation[i] = 0f; } if (alpha == 1f) { rotateTimeline.Apply(skeleton, 0f, time, null, 1f, pose, MixDirection.In); } else { Bone bone = skeleton.bones.Items[rotateTimeline.boneIndex]; float[] frames = rotateTimeline.frames; if (time < frames[0]) { if (pose == MixPose.Setup) { bone.rotation = bone.data.rotation; } } else { float num; float num7; if (time >= frames[frames.Length - 2]) { num = bone.data.rotation + frames[frames.Length + -1]; } else { int index = Animation.BinarySearch(frames, time, 2); float num3 = frames[index + -1]; float num4 = frames[index]; float curvePercent = rotateTimeline.GetCurvePercent((index >> 1) - 1, 1f - ((time - num4) / (frames[index + -2] - num4))); num = frames[index + 1] - num3; num -= (0x4000 - ((int)(16384.499999999996 - (num / 360f)))) * 360; num = (num3 + (num * curvePercent)) + bone.data.rotation; num -= (0x4000 - ((int)(16384.499999999996 - (num / 360f)))) * 360; } float num6 = (pose != MixPose.Setup) ? bone.rotation : bone.data.rotation; float num8 = num - num6; if (num8 == 0f) { num7 = timelinesRotation[i]; } else { float num9; float num10; num8 -= (0x4000 - ((int)(16384.499999999996 - (num8 / 360f)))) * 360; if (firstFrame) { num9 = 0f; num10 = num8; } else { num9 = timelinesRotation[i]; num10 = timelinesRotation[i + 1]; } bool flag = num8 > 0f; bool flag2 = num9 >= 0f; if ((Math.Sign(num10) != Math.Sign(num8)) && (Math.Abs(num10) <= 90f)) { if (Math.Abs(num9) > 180f) { num9 += 360 * Math.Sign(num9); } flag2 = flag; } num7 = (num8 + num9) - (num9 % 360f); if (flag2 != flag) { num7 += 360 * Math.Sign(num9); } timelinesRotation[i] = num7; } timelinesRotation[i + 1] = num8; num6 += num7 * alpha; bone.rotation = num6 - ((0x4000 - ((int)(16384.499999999996 - (num6 / 360f)))) * 360); } } }