public static void Transform(ref Vector2 position, ref Quaternion quat, out Vector2 result) { Quaternion result1 = new Quaternion(position.X, position.Y, 0.0f, 0.0f); Quaternion result2; Quaternion.Inverse(ref quat, out result2); Quaternion result3; Quaternion.Multiply(ref quat, ref result1, out result3); Quaternion.Multiply(ref result3, ref result2, out result1); result = new Vector2(result1.X, result1.Y); }
/// <summary> /// Creates a new <see cref="Vector2"/> that contains a transformation of 2d-vector by the specified <see cref="Quaternion"/>, representing the rotation. /// </summary> /// <param name="value">Source <see cref="Vector2"/>.</param> /// <param name="rotation">The <see cref="Quaternion"/> which contains rotation transformation.</param> /// <param name="result">Transformed <see cref="Vector2"/> as an output parameter.</param> public static void Transform( ref Vector2 value, ref Quaternion rotation, out Vector2 result ) { Quaternion v = new Quaternion(value.X, value.Y, 0, 0), i, t; Quaternion.Inverse(ref rotation, out i); Quaternion.Multiply(ref rotation, ref v, out t); Quaternion.Multiply(ref t, ref i, out v); result.X = v.X; result.Y = v.Y; }
public static void Transform( ref Vector2 position, ref Quaternion quat, out Vector2 result ) { Quaternion v = new Quaternion(position.X, position.Y, 0, 0), i, t; Quaternion.Inverse(ref quat, out i); Quaternion.Multiply(ref quat, ref v, out t); Quaternion.Multiply(ref t, ref i, out v); result.X = v.X; result.Y = v.Y; }
protected override void Execute(List <CommandEntity> entities) { foreach (var e in entities) { var playerEntities = m_contexts.game.GetEntitiesWithPlayerId(e.commandOwner.value); if (playerEntities.Count == 0) { continue; } var playerEntity = playerEntities.SingleEntity(); if (e.moveCommand.value.LengthSquared() > 0.1f) { float angularSpeed = playerEntity.angularSpeed.value; Vector3 dir = playerEntity.direction.value; Vector3 targetDir = e.moveCommand.value; // dot(dir, rot90CCW(targetDir)) float angle = 0f; float dot = dir.X * -targetDir.Y + dir.Y * targetDir.X; // parallel/antiparallel if (Math.Abs(dot) <= ANGLE_TOLERANCE) { Services.Get <ILogService>().LogInfo("parallel/antiparallel"); if (Vector3.Dot(dir, targetDir) < 0f) { angle = angularSpeed * m_timeService.FrameInterval; } } // targetDir is in right of dir, else if (dot > float.Epsilon) { Services.Get <ILogService>().LogInfo("targetDir is in right of dir " + dot.ToString()); angle = -angularSpeed * m_timeService.FrameInterval; float d = MathHelper.ToDegrees((float)Math.Acos(dot)) - 90f; // over rotation if (Math.Abs(angle) > Math.Abs(d)) { angle = d; } } // targetDir is in left of dir else { Services.Get <ILogService>().LogInfo("targetDir is in left of dir" + dot.ToString()); angle = angularSpeed * m_timeService.FrameInterval; float d = MathHelper.ToDegrees((float)Math.Acos(dot)) - 90f; // over rotate if (Math.Abs(angle) > Math.Abs(d)) { angle = d; } } var quat = Quaternion.CreateFromAxisAngle(Vector3.Backward, MathHelper.ToRadians(angle)); var targetQuat = Quaternion.Multiply(playerEntity.rotation.value, quat); playerEntity.ReplaceRotation(targetQuat); playerEntity.ReplaceDirection(Vector3.Normalize(Vector3.Transform(Vector3.Right, targetQuat))); playerEntity.ReplaceSpeed(playerEntity.speed.maxValue, playerEntity.speed.maxValue); } else { playerEntity.ReplaceSpeed(0f, playerEntity.speed.maxValue); } } }