public void TestScale() { Vector3 scalingVector = new Vector3(0.5f, 0.5f, 0.5f); transManager.Scale(scalingVector); Assert.IsTrue(scalingVector.Equals(go.transform.localScale)); }
/// <summary> /// Called when a manipulation gesture is currently happening /// </summary> /// <param name="eventData">The data of the manipulation event</param> public void OnManipulationUpdated(ManipulationEventData eventData) { if (transformationManager.enabled) { // compute the difference of the drag gesture in comparison to the last frame // this way the rotation speed is not accumulating but only depends on the current drag speed Vector3 delta = lastCummulativeDelta - eventData.CumulativeDelta; delta *= -1; switch (handleType) { case HandleType.SCALE: { // it is also possible to scale without preserving the aspect ratio // this option is implemented in here but it is currently not used bool preserveAspectRatio = true; if (preserveAspectRatio) { Vector2 centerProj = Camera.main.WorldToScreenPoint(toManipulate.position); Vector2 handleProj = Camera.main.WorldToScreenPoint(transform.position); Vector2 fromCenterToHandle = handleProj - centerProj; fromCenterToHandle = fromCenterToHandle.normalized; int drawDirection = Math.Sign(Vector2.Dot(delta, fromCenterToHandle)); // fromCenterToHandle points outwards from the center // thus: // if drawDirection < 0: inwards-drag => scale down // if drawDirection > 0: outwards-drag => scale up // just get the most dominant 2D-axis to determine the strength of the scale // float max = Math.Max(Math.Abs(delta.x), Math.Abs(delta.y)); // get the length of the drag vector in order to determine the strength of the operation float max = delta.magnitude; // determine scaling factor float scaleFac = 1.0f + (speed * max * drawDirection); #if BOUNDING_BOX_DEBUG // the following are debug lines which can be used to visualize the relevant vectors // they are only visible in the game view //Debug.DrawLine(toManipulate.position, toManipulate.position + new Vector3(fromCenterToHandle.x, fromCenterToHandle.y, 0), Color.red); //Debug.DrawLine(Camera.main.transform.position, Camera.main.transform.position + (delta * 10000), Color.cyan); #endif // scale transformationManager.Scale(scaleFac * Vector3.one); } else { Vector3 scaleVec = speed * new Vector3( delta.x * gestureOrientation.x, delta.y * gestureOrientation.y, delta.z * gestureOrientation.z); transformationManager.Scale(scaleVec); } break; } case HandleType.ROTATE: { // it uses the projection of the axis and computes everything in the viewport plane Vector3 projectedDelta = Vector3.Project(delta, projectionCross); float rotationAngle = projectedDelta.magnitude * Vector3.Dot(projectedDelta.normalized, projectionCross.normalized) * 360; #if BOUNDING_BOX_DEBUG // the following are debug lines which can be used to visualize the relevant vectors // they are only visible in the game view //Debug.DrawLine(toManipulate.position, toManipulate.position + currentAxis, Color.red); //Debug.DrawLine(Camera.main.transform.position, Camera.main.transform.position + currentAxisProjection, Color.magenta); //Debug.DrawLine(Camera.main.transform.position, Camera.main.transform.position + projectionCross, Color.green); //Debug.DrawLine(Camera.main.transform.position, Camera.main.transform.position + (projectedDelta * 10000), Color.blue); //Debug.DrawLine(Camera.main.transform.position, Camera.main.transform.position + (delta * 10000), Color.cyan); #endif #if ALTERNATIVE_SOLUTION // this solution determines the angle at the object between the camera and its offset by the drag vector // with the aid of the cross product the "sign of the angle" can be determined // i.e. if the drag direction is pointing to the left or the right of the axis as seen from the camera Vector3 objToCam = Camera.main.transform.position - toManipulate.position; Vector3 objToTarget = (Camera.main.transform.position + delta) - toManipulate.position; float rotationAngle = Vector3.Angle(objToCam, objToTarget); Vector3 crossProduct = Vector3.Cross(objToCam, objToTarget); if (Vector3.Dot(crossProduct, currentAxis) < 0) { rotationAngle *= -1; } #endif Debug.Log("Rotation by: " + rotationAngle); // rotate around the given axis by the calculated angle transformationManager.Rotate(gestureOrientation, speed * rotationAngle); break; } case HandleType.TRANSLATE: { transformationManager.Translate(speed * delta); break; } } // remember the cumulativeDelta in order to calculate the difference to this in the next frame lastCummulativeDelta = eventData.CumulativeDelta; } }