/// <summary> /// Rotates the given <see cref="TransformComponent"/> by the specified <paramref name="eulerAngles"/> in the coordinate space defined by <paramref name="relativeTo"/>. /// </summary> /// <param name="transform">The <see cref="TransformComponent"/> to update.</param> /// <param name="eulerAngles">The euler angles in radians to rotate by.</param> /// <param name="relativeTo">The coordinate space to perform the rotation in.</param> /// <exception cref="ArgumentNullException">If <paramref name="transform"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException">If <paramref name="transform"/> has <see cref="TransformComponent.UseTRS"/> set to <see langword="null"/>.</exception> /// <remarks> /// This method updates the <see cref="TransformComponent.LocalMatrix"/> and <see cref="TransformComponent.WorldMatrix"/> after transformation. /// </remarks> public static void Rotate(this TransformComponent transform, ref Vector3 eulerAngles, Space relativeTo = Space.Self) { if (transform == null) { throw new ArgumentNullException(nameof(transform)); } if (!transform.UseTRS) { throw new ArgumentException("Must use TRS", nameof(transform)); } Quaternion rotation = Quaternion.Identity; if (relativeTo == Space.Self) { //What do I do here??? if (eulerAngles.X != 0f) { var right = transform.WorldMatrix.Right; right.Normalize(); Quaternion.RotationAxis(ref right, eulerAngles.X, out var axisRotation); Quaternion.Multiply(ref rotation, ref axisRotation, out rotation); } if (eulerAngles.Y != 0f) { var up = transform.WorldMatrix.Up; up.Normalize(); Quaternion.RotationAxis(ref up, eulerAngles.Y, out var axisRotation); Quaternion.Multiply(ref rotation, ref axisRotation, out rotation); } if (eulerAngles.Z != 0f) { var forward = transform.WorldMatrix.Forward; forward.Normalize(); Quaternion.RotationAxis(ref forward, eulerAngles.Z, out var axisRotation); Quaternion.Multiply(ref rotation, ref axisRotation, out rotation); } } else { //Quaternion.RotationYawPitchRoll(eulerAngles.Y, eulerAngles.X, eulerAngles.Z, out rotation); MathUtilEx.ToQuaternion(ref eulerAngles, out rotation); } if (transform.Parent != null) { transform.Parent.WorldMatrix.Decompose(out var _, out Quaternion parentRotation, out var _); parentRotation.Conjugate(); Quaternion.Multiply(ref rotation, ref parentRotation, out rotation); } Quaternion.Multiply(ref transform.Rotation, ref rotation, out transform.Rotation); transform.UpdateWorldMatrix(); }
public override async Task Execute() { var bottom = new Vector3(0, Height, 0); var duration = TimeSpan.FromSeconds(2); var elapsed = TimeSpan.Zero; var easingFunctions = ((EasingFunction[])Enum.GetValues(typeof(EasingFunction))).Reverse().ToList(); easingFunctions.RemoveAt(0); { var startPosition = FirstPosition; var endPosition = FirstPosition - bottom; var sphere = SpherePrefab.InstantiateSingle(FirstPosition); Entity.Scene.Entities.Add(sphere); Script.AddOverTimeAction((progress) => { sphere.Transform.Position = MathUtilEx.Interpolate(startPosition, endPosition, progress, EasingFunction.ElasticEaseOut); }, TimeSpan.FromSeconds(2)); } var startPositions = new List <Vector3>(); var transforms = new List <TransformComponent>(); for (int i = 0; i < easingFunctions.Count; i++) { Vector3 startPosition = FirstPosition + new Vector3(i + 1, 0, 0); var sphere = SpherePrefab.InstantiateSingle(startPosition); transforms.Add(sphere.Transform); startPositions.Add(startPosition); Entity.Scene.Entities.Add(sphere); } var ran = new Random(); var colors = Enumerable.Range(0, transforms.Count).Select(i => ran.NextColor()).ToList(); while (Game.IsRunning) { var progress = (float)(elapsed.TotalSeconds / duration.TotalSeconds); if (progress > 1.0f) { progress = 1.0f; } DebugText.Print($"Progress = {progress}", new Int2(10)); for (int i = 0; i < transforms.Count; i++) { var t = transforms[i]; var easing = easingFunctions[i]; t.Position = MathUtilEx.Interpolate(startPositions[i], startPositions[i] - bottom, progress, easing); var diffuse = MathUtilEx.Interpolate(Color.White, colors[i], progress, EasingFunction.Linear); t.Entity.Get <ModelComponent>().SetMaterialParameter(MaterialKeys.DiffuseValue, diffuse); } elapsed += Game.UpdateTime.Elapsed; if (Input.IsKeyPressed(Xenko.Input.Keys.Space)) { //reset elapsed = TimeSpan.Zero; } await Script.NextFrame(); } }