public bool PerformAndValidate(PerformArguments performArguments, Matrix4x4 priorTransform, ref Matrix4x4 newTransform) { // For PerformAndValidate the call tree goes: // IBehavior-override->Combined-calls->Principal-usessuperclass->IBehavior // Then inside here we do Perform and do a Validate // Reset the HashSet performArguments.ActionsApplied = new HashSet <ActionsApplied>(); if (!this.Perform(performArguments, priorTransform, ref newTransform)) { // Failed to perform (e.g. not enough cursors) return(false); } else { // Performed if (performArguments.ValidateFunction == null) { // No Constraints required return(true); } else { // Check if passed Constraints var success = performArguments.ValidateFunction(new ValidateFunctionArguments { Transform = newTransform, ActionsApplied = performArguments.ActionsApplied }); return(success); } } }
public override bool Perform(PerformArguments performArguments, Matrix4x4 oldTransform, ref Matrix4x4 newTransform) { var cursorCount = performArguments.Cursors.Count(); if (cursorCount < 2) { return(false); } performArguments.ActionsApplied.Add(ActionsApplied.Rotate); performArguments.ActionsApplied.Add(ActionsApplied.Translate); // We split the cursors in half, the half with the largest movement are the rotation, the half with the lowest movement are the pivot var cursorsSortedByMovement = performArguments.Cursors.OrderBy(cursor => cursor.Movement.LengthSquared).ToList(); var cursorCountForPivot = (int)Math.Ceiling((double)cursorCount / 2); var cursorsForPivot = cursorsSortedByMovement.GetRange(0, cursorCountForPivot); var cursorsForRotation = cursorsSortedByMovement.GetRange(cursorCountForPivot, cursorCount - cursorCountForPivot); var pivot = Utils.MeanPosition(cursorsForPivot); // Take the total rotation double totalRotation = 0.0; foreach (var cursor in cursorsForRotation) { var currentCursorPositionVSCOM = cursor.Position - pivot; var previousCursorPositionVSCOM = currentCursorPositionVSCOM - cursor.Movement; var rotationFromCursor = Math.Atan2(currentCursorPositionVSCOM.y, currentCursorPositionVSCOM.x) - Math.Atan2(previousCursorPositionVSCOM.y, previousCursorPositionVSCOM.x); totalRotation += rotationFromCursor; } var averageRotation = totalRotation / cursorsForRotation.Count(); newTransform = oldTransform * VMath.Translate(-pivot.x, -pivot.y, 0.0) * VMath.RotateZ(averageRotation) * VMath.Translate(pivot.x, pivot.y, 0.0); if (cursorsForPivot.Count > 0) { var totalTranslation = new Vector2D(0.0, 0.0); foreach (var cursor in cursorsForPivot) { totalTranslation += cursor.Movement; } var averageTranslation = totalTranslation / cursorsForPivot.Count(); newTransform = newTransform * VMath.Translate(new Vector3D(averageTranslation)); } return(true); }
public override bool Perform(PerformArguments performArguments, Matrix4x4 oldTransform, ref Matrix4x4 newTransform) { var cursorCount = performArguments.Cursors.Count(); if (cursorCount < 1) { // We should never arrive here return(false); } if (cursorCount < 2) { // revert to translate only return(TranslateNode.PrincipalBehavior.Perform(performArguments, oldTransform, ref newTransform)); } performArguments.ActionsApplied.Add(ActionsApplied.Translate); performArguments.ActionsApplied.Add(ActionsApplied.Rotate); performArguments.ActionsApplied.Add(ActionsApplied.Scale); //choose the cursors with the most movement var cursorsSortedByMovement = performArguments.Cursors.OrderByDescending(cursor => cursor.Movement.LengthSquared).ToList(); var cursor0Now = cursorsSortedByMovement[0].Position; var cursor1Now = cursorsSortedByMovement[1].Position; var cursor0Previous = cursorsSortedByMovement[0].Position - cursorsSortedByMovement[0].Movement; var cursor1Previous = cursorsSortedByMovement[1].Position - cursorsSortedByMovement[1].Movement; double num1 = (double)cursor0Previous.x; double num2 = (double)cursor0Previous.y; double num3 = (double)cursor1Previous.x; double num4 = (double)cursor1Previous.y; double num5 = (double)cursor0Now.x; double num6 = (double)cursor0Now.y; double num7 = (double)cursor1Now.x; double num8 = (double)cursor1Now.y; double num9 = num3 - num1; double num10 = num4 - num2; double num11 = num7 - num5; double num12 = num8 - num6; Math.Sqrt((num11 * num11 + num12 * num12) / (num9 * num9 + num10 * num10)); double num13 = (num9 * num11 + num10 * num12) / (num9 * num9 + num10 * num10); double num14 = (num10 * num11 - num9 * num12) / (num9 * num9 + num10 * num10); double num15 = num5 - (num13 * num1 + num14 * num2); double num16 = num6 - (-num14 * num1 + num13 * num2); newTransform = oldTransform * new Matrix4x4(num13, -num14, 0.0, 0.0, num14, num13, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, num15, num16, 0.0, 1.0); return(true); }
/// <summary> /// Perform any multi-touch actions /// </summary> public void Update() { if (this.AttachedCursors.Count > 0) { // Find the Behavior for the multitouch action var behaviorChain = this.Behavior; if (behaviorChain == null) { //default to full multitouch behaviorChain = Behaviors.FullMultitouchNode.PrincipalBehavior; } // Setup the arguments to perform the Behavior var performArguments = new Behaviors.PerformArguments { Cursors = this.AttachedCursors }; // If we have constraints, add the settings to the performArguments if (this.Constraint != null) { var checkConstraintArguments = new Constraints.CheckConstraintArguments { Slide = this }; performArguments.ValidateFunction = (Behaviors.ValidateFunctionArguments validateFunctionArguments) => { return(this.Constraint.CheckConstraint(validateFunctionArguments, checkConstraintArguments)); }; } // Perform the behavior chain (inside the chain it checks relevant Constraints and at // each point in the tree uses fallback behavior if Constraints are not met if any) { Matrix4x4 newTransform = this.Transform; // this will always be overwritten - it's just the cheapest thing here to use as a dummy if (behaviorChain.PerformAndValidate(performArguments, this.Transform, ref newTransform)) { this.Transform = newTransform; } else { // No matching of behaviors and constraints could be met } } } }
public override bool Perform(PerformArguments performArguments, Matrix4x4 oldTransform, ref Matrix4x4 newTransform) { var cursorCount = performArguments.Cursors.Count(); if (cursorCount < 2) { // Cannot perform Behaviour return(false); } performArguments.ActionsApplied.Add(ActionsApplied.Translate); performArguments.ActionsApplied.Add(ActionsApplied.Scale); // We split the cursors in half, the half with the largest movement are the rotation, the half with the lowest movement are the pivot var cursorsSortedByMovement = performArguments.Cursors.OrderBy(cursor => cursor.Movement.LengthSquared).ToList(); var cursorCountForPivot = cursorCount / 2; var cursorsForPivot = cursorsSortedByMovement.GetRange(0, cursorCountForPivot); var cursorsForAction = cursorsSortedByMovement.GetRange(cursorCountForPivot, cursorCount - cursorCountForPivot); var pivot = Utils.MeanPosition(cursorsForPivot); // Take the total rotation double totalScale = 1.0; foreach (var cursor in cursorsForAction) { var currentCursorPositionVSCOM = cursor.Position - pivot; var previousCursorPositionVSCOM = currentCursorPositionVSCOM - cursor.Movement; var scaleFromCursor = currentCursorPositionVSCOM.Length / previousCursorPositionVSCOM.Length; totalScale *= scaleFromCursor; } var averageScale = Math.Pow(totalScale, 1 / cursorsForAction.Count()); newTransform = oldTransform * VMath.Translate(-pivot.x, -pivot.y, 0.0) * VMath.Scale(totalScale, totalScale, 1.0) * VMath.Translate(pivot.x, pivot.y, 0.0); return(true); }
public override bool Perform(PerformArguments performArguments, Matrix4x4 oldTransform, ref Matrix4x4 newTransform) { if (performArguments.Cursors.Count() < 1) { // Cannot perform Behaviour return(false); } performArguments.ActionsApplied.Add(ActionsApplied.Translate); var totalTranslation = new Vector2D(0.0, 0.0); foreach (var cursor in performArguments.Cursors) { totalTranslation += cursor.Movement; } var averageTranslation = totalTranslation / performArguments.Cursors.Count(); newTransform = oldTransform * VMath.Translate(new Vector3D(averageTranslation)); return(true); }
public bool PerformAndValidate(PerformArguments performArguments, Matrix4x4 priorTransform, ref Matrix4x4 newTransform) { bool success = false; if (this.Principal != null) { newTransform = new Matrix4x4(); success = this.Principal.PerformAndValidate(performArguments, priorTransform, ref newTransform); } if (!success) { // Neither the principal or the AlsoTry succeeded, try the fall-back action if (this.Fallback != null) { newTransform = new Matrix4x4(); success = this.Fallback.PerformAndValidate(performArguments, priorTransform, ref newTransform); } } return(success); }
abstract public bool Perform(PerformArguments performArguments, Matrix4x4 transform, ref Matrix4x4 newTransform);