コード例 #1
0
        public void RotateUsingKeyboardSettings(TransformAxis rotationAxis)
        {
            if (IsAnyMouseSessionActive)
            {
                return;
            }

            ObjectKeyboardRotationSettings keyboardRotationSettings = ObjectPlacementGuideSettings.Get().KeyboardRotationSettings;

            UndoEx.RecordForToolAction(_transform);

            AxisKeyboardRotationSettings axisKeyboardRotationSettings = keyboardRotationSettings.XAxisRotationSettings;

            if (rotationAxis == TransformAxis.Y)
            {
                axisKeyboardRotationSettings = keyboardRotationSettings.YAxisRotationSettings;
            }
            else if (rotationAxis == TransformAxis.Z)
            {
                axisKeyboardRotationSettings = keyboardRotationSettings.XAxisRotationSettings;
            }

            gameObject.RotateHierarchyBoxAroundPoint(axisKeyboardRotationSettings.RotationAmountInDegrees,
                                                     TransformAxes.GetVector(rotationAxis, TransformSpace.Global, _transform),
                                                     gameObject.GetHierarchyWorldOrientedBox().Center);

            UndoEx.RecordForToolAction(_sourcePrefab.ActivationSettings);
            _sourcePrefab.ActivationSettings.WorldRotation = _transform.rotation;
        }
コード例 #2
0
 public void BeginMouseRotationSession(TransformAxis rotationAxis)
 {
     if (!IsAnyMouseSessionActive)
     {
         _mouseRotationSession.BeginRotationAroundAxis(gameObject, ObjectPlacementSettings.Get().ObjectPlacementGuideSettings.MouseRotationSettings, rotationAxis);
     }
 }
コード例 #3
0
    /// <summary>
    /// Rotate the currently selected snowman scene node
    /// </summary>
    /// <param name="axis"></param>
    /// <param name="speed"></param>
    private void RotateNode(TransformAxis axis, int speed)
    {
        Vector3    rotationAxis    = world.GetCurrentRotationAxis(axis);
        Quaternion currentRotation = world.GetCurrentRotation();
        Quaternion appliedRotation = Quaternion.AngleAxis(speed, rotationAxis);

        currentRotation = appliedRotation * currentRotation;
        world.SetSnowmanNodeRotation(currentRotation);
    }
コード例 #4
0
 public static Vector3 GetVector(TransformAxis axis, TransformSpace transformSpace, Transform transform)
 {
     if (transformSpace == TransformSpace.Local)
     {
         return(GetTransformLocalVector(axis, transform));
     }
     else
     {
         return(GetGlobalVector(axis));
     }
 }
コード例 #5
0
 public static Vector3 GetTransformLocalVector(TransformAxis axis, Transform transform)
 {
     if (axis == TransformAxis.X)
     {
         return(transform.right);
     }
     if (axis == TransformAxis.Y)
     {
         return(transform.up);
     }
     return(transform.forward);
 }
コード例 #6
0
        public static Vector3 Mirror(this Vector3 source, TransformAxis axis)
        {
            switch (axis)
            {
            case TransformAxis.X: return(new Vector3(-source.x, source.y, source.z));

            case TransformAxis.Y: return(new Vector3(source.x, -source.y, source.z));

            case TransformAxis.Z: return(new Vector3(source.x, source.y, -source.z));

            default: return(source);
            }
        }
コード例 #7
0
        protected bool IsTouchingWall()
        {
            bool isTouchingWall;

            Vector2 lineCastPosition = transform.position - TransformAxis * SpriteWidth - transform.up * SpriteHeight * wallCheckLinePosition;

            Debug.DrawLine(lineCastPosition, lineCastPosition - TransformAxis.toVector2() * wallCheckLineLength);

            isTouchingWall = Physics2D.Linecast(lineCastPosition,
                                                lineCastPosition - transform.right.toVector2() * wallCheckLineLength,
                                                whatIsWall);

            return(isTouchingWall);
        }
コード例 #8
0
        public void BeginRotationAroundAxis(GameObject gameObject, ObjectMouseRotationSettings rotationSettings, TransformAxis rotationAxis)
        {
            if (gameObject != null && !_isActive)
            {
                _isActive            = true;
                _gameObject          = gameObject;
                _gameObjectTransform = _gameObject.transform;

                _mouseRotationSettings        = rotationSettings;
                _rotationAxis                 = rotationAxis;
                _rotatingAroundCustomAxis     = false;
                _accumulatedRotationInDegrees = 0.0f;
            }
        }
コード例 #9
0
        /// <summary>
        /// Obtiene los ejes de transformación de la primitiva.
        /// </summary>
        /// <param name="axis">Eje</param>
        public Vector3 GetAxis(TransformAxis axis)
        {
            if (axis == TransformAxis.X)
            {
                return(this.XAxis);
            }
            else if (axis == TransformAxis.Y)
            {
                return(this.YAxis);
            }
            else if (axis == TransformAxis.Z)
            {
                return(this.ZAxis);
            }

            throw new NotSupportedException("Tipo de eje no soportado: " + axis.ToString());
        }
コード例 #10
0
        /// <summary>
        /// Desplaza uno solo de los componentes de la posición global de esta instancia.
        /// </summary>
        /// <param name="transform"></param>
        /// <param name="axis">Eje a lo largo del cual efectuar el desplazamiento.</param>
        /// <param name="value">Valor a añadir a lo largo del eje especificado.</param>
        public static void TranslateByAxis(this Transform transform, TransformAxis axis, float value)
        {
            switch (axis)
            {
            case TransformAxis.X:
                transform.position += new Vector3(value, 0.0f, 0.0f);
                break;

            case TransformAxis.Y:
                transform.position += new Vector3(0.0f, value, 0.0f);
                break;

            case TransformAxis.Z:
                transform.position += new Vector3(0.0f, 0.0f, value);
                break;
            }
        }
コード例 #11
0
        /// <summary>
        /// Rota uno solo de los componentes de rotación de esta instancia según el espacio de coordenadas global.
        /// </summary>
        /// <param name="transform"></param>
        /// <param name="axis">Eje a lo largo del cual efectuar la rotación.</param>
        /// <param name="angle">Ángulo a añadir en torno al eje especificado.</param>
        public static void RotateByAxis(this Transform transform, TransformAxis axis, float angle)
        {
            switch (axis)
            {
            case TransformAxis.X:
                transform.rotation *= Quaternion.AngleAxis(angle, Vector3.right);
                break;

            case TransformAxis.Y:
                transform.rotation *= Quaternion.AngleAxis(angle, Vector3.up);
                break;

            case TransformAxis.Z:
                transform.rotation *= Quaternion.AngleAxis(angle, Vector3.forward);
                break;
            }
        }
コード例 #12
0
        /// <summary>
        /// Obtiene los ejes de transformación de la primitiva.
        /// </summary>
        /// <param name="axis">Eje</param>
        public Vector3 GetAxis(TransformAxis axis)
        {
            if (axis == TransformAxis.X)
            {
                return(this.XAxis);
            }
            else if (axis == TransformAxis.Y)
            {
                return(this.YAxis);
            }
            else if (axis == TransformAxis.Z)
            {
                return(this.ZAxis);
            }

            throw new NotImplementedException();
        }
コード例 #13
0
    /// <summary>
    /// Get the display name of a given axis type
    /// </summary>
    /// <param name="axis"></param>
    /// <returns></returns>
    private string GetTransformAxisName(TransformAxis axis)
    {
        switch (axis)
        {
        case TransformAxis.X:
            return("X");

        case TransformAxis.Y:
            return("Y");

        case TransformAxis.Z:
            return("Z");

        default:
            return(string.Empty);
        }
    }
コード例 #14
0
    /// <summary>
    /// Get the current snowman node axis of rotation (right, up, forward)
    /// </summary>
    /// <param name="axis"></param>
    /// <returns></returns>
    public Vector3 GetCurrentRotationAxis(TransformAxis axis)
    {
        SceneNode node = GetSnowmanSceneNode();

        if (node != null)
        {
            switch (axis)
            {
            case TransformAxis.X:
                return(node.transform.right);

            case TransformAxis.Y:
                return(node.transform.up);

            case TransformAxis.Z:
                return(node.transform.forward);
            }
        }
        return(Vector3.zero);
    }
コード例 #15
0
    /// <summary>
    /// Scale the currently selected snowman scene node
    /// </summary>
    /// <param name="axis"></param>
    /// <param name="speed"></param>
    private void ScaleNode(TransformAxis axis, int speed)
    {
        Vector3 currentNodeScale = world.GetCurrentScale();

        switch (axis)
        {
        case TransformAxis.X:
            currentNodeScale.x += speed * Time.smoothDeltaTime;
            break;

        case TransformAxis.Y:
            currentNodeScale.y += speed * Time.smoothDeltaTime;
            break;

        case TransformAxis.Z:
            currentNodeScale.z += speed * Time.smoothDeltaTime;
            break;
        }
        world.SetSnowmanNodeScale(currentNodeScale);
    }
コード例 #16
0
    /// <summary>
    /// Translate the currently selected snowman scene node
    /// </summary>
    /// <param name="axis"></param>
    /// <param name="speed"></param>
    private void TranslateNode(TransformAxis axis, int speed)
    {
        Vector3 currentNodePosition = world.GetCurrentNodePosition();

        switch (axis)
        {
        case TransformAxis.X:
            currentNodePosition.x += speed * Time.smoothDeltaTime;
            break;

        case TransformAxis.Y:
            currentNodePosition.y += speed * Time.smoothDeltaTime;
            break;

        case TransformAxis.Z:
            currentNodePosition.z += speed * Time.smoothDeltaTime;
            break;
        }
        world.SetSnowmanNodePosition(currentNodePosition);
    }
コード例 #17
0
    /// <summary>
    /// Update the transform of the currently selected snowman scene node
    /// </summary>
    /// <param name="speed"></param>
    private void UpdateNodeTransform(int speed)
    {
        TransformMode currentTransformMode = transformModeOptions[transformModeIndex];
        TransformAxis currentTransformAxis = transformAxisOptions[transformAxisIndex];

        switch (currentTransformMode)
        {
        case TransformMode.TRANSLATE:
            TranslateNode(currentTransformAxis, speed);
            break;

        case TransformMode.SCALE:
            ScaleNode(currentTransformAxis, speed);
            break;

        case TransformMode.ROTATE:
            RotateNode(currentTransformAxis, speed);
            break;
        }
    }
コード例 #18
0
        /// <summary>
        /// Rota uno solo de los componentes de rotación de esta instancia según el espacio de coordenadas
        /// especificado.
        /// </summary>
        /// <param name="transform"></param>
        /// <param name="axis">Eje a lo largo del cual efectuar la rotación.</param>
        /// <param name="angle">Ángulo a añadir en torno al eje especificado.</param>
        /// <param name="transformSpace">Espacio de coordenadas a utilizar.</param>
        public static void RotateByAxis(this Transform transform, TransformAxis axis, float angle,
                                        Space transformSpace)
        {
            switch (axis)
            {
            case TransformAxis.X:
                if (transformSpace == Space.World)
                {
                    transform.rotation *= Quaternion.AngleAxis(angle, Vector3.right);
                }
                else
                {
                    transform.Rotate(angle, 0.0f, 0.0f, Space.Self);
                }
                break;

            case TransformAxis.Y:
                if (transformSpace == Space.World)
                {
                    transform.rotation *= Quaternion.AngleAxis(angle, Vector3.up);
                }
                else
                {
                    transform.Rotate(0.0f, angle, 0.0f, Space.Self);
                }
                break;

            case TransformAxis.Z:
                if (transformSpace == Space.World)
                {
                    transform.rotation *= Quaternion.AngleAxis(angle, Vector3.forward);
                }
                else
                {
                    transform.Rotate(0.0f, 0.0f, angle, Space.Self);
                }
                break;
            }
        }
コード例 #19
0
        /// <summary>
        /// Desplaza uno solo de los componentes de la posición de esta instancia en el espacio de coordenadas
        /// especificado.
        /// </summary>
        /// <param name="transform"></param>
        /// <param name="axis">Eje a lo largo del cual efectuar el desplazamiento.</param>
        /// <param name="value">Valor a añadir a lo largo del eje especificado.</param>
        /// <param name="transformSpace">Espacio de coordenadas a utilizar.</param>
        public static void TranslateByAxis(this Transform transform, TransformAxis axis, float value,
                                           Space transformSpace)
        {
            switch (axis)
            {
            case TransformAxis.X:
                if (transformSpace == Space.World)
                {
                    transform.position += new Vector3(value, 0.0f, 0.0f);
                }
                else
                {
                    transform.localPosition += new Vector3(value, 0.0f, 0.0f);
                }
                break;

            case TransformAxis.Y:
                if (transformSpace == Space.World)
                {
                    transform.position += new Vector3(0.0f, value, 0.0f);
                }
                else
                {
                    transform.localPosition += new Vector3(0.0f, value, 0.0f);
                }
                break;

            case TransformAxis.Z:
                if (transformSpace == Space.World)
                {
                    transform.position += new Vector3(0.0f, 0.0f, value);
                }
                else
                {
                    transform.localPosition += new Vector3(0.0f, 0.0f, value);
                }
                break;
            }
        }
コード例 #20
0
        public void OnSceneGUIUpdate()
        {
            if (_sharedHotkeys == null || _sharedSettings == null)
            {
                return;
            }

            if (IsActive)
            {
                var   deviceManager = InputDeviceManager.Get;
                State oldState      = _state;
                if (SharedHotkeys.EnableOffsetFromAnchor.IsActive())
                {
                    if (_state != State.ActiveOffsetFromAnchor &&
                        deviceManager.CreateMouseDeltaCapture(deviceManager.MousePos, out _deltaCaptureId))
                    {
                        StoreGrabTargetsAnchorVectorSnapshots();
                        _state = State.ActiveOffsetFromAnchor;
                    }
                }
                else if (SharedHotkeys.EnableAnchorAdjust.IsActive())
                {
                    _state = State.ActiveAnchorAdjust;
                }
                else if (SharedHotkeys.EnableRotation.IsActive())
                {
                    _state = State.ActiveRotate;
                }
                else if (SharedHotkeys.EnableRotationAroundAnchor.IsActive())
                {
                    _state = State.ActiveRotateAroundAnchor;
                }
                else if (SharedHotkeys.EnableScaling.IsActive())
                {
                    if (_state != State.ActiveScale &&
                        deviceManager.CreateMouseDeltaCapture(deviceManager.MousePos, out _deltaCaptureId))
                    {
                        StoreGrabTargetsWorldScaleSnapshots();
                        _state = State.ActiveScale;
                    }
                }
                else if (SharedHotkeys.EnableOffsetFromSurface.IsActive())
                {
                    _state = State.ActiveOffsetFromSurface;
                }
                else
                {
                    _state = State.ActiveSnapToSurface;
                }

                if (_state != State.ActiveScale &&
                    _state != State.ActiveOffsetFromAnchor)
                {
                    deviceManager.RemoveMouseDeltaCapture(_deltaCaptureId);
                }

                if (_state == State.ActiveSnapToSurface)
                {
                    TransformAxis currentAxis = SharedSettings.AlignmentAxis;
                    if (_sharedHotkeys.SwitchToXAlignmentAxis.IsActive())
                    {
                        if (currentAxis == TransformAxis.PositiveX)
                        {
                            SharedSettings.AlignmentAxis = TransformAxis.NegativeX;
                        }
                        else
                        {
                            SharedSettings.AlignmentAxis = TransformAxis.PositiveX;
                        }
                    }
                    else if (_sharedHotkeys.SwitchToYAlignmentAxis.IsActive())
                    {
                        if (currentAxis == TransformAxis.PositiveY)
                        {
                            SharedSettings.AlignmentAxis = TransformAxis.NegativeY;
                        }
                        else
                        {
                            SharedSettings.AlignmentAxis = TransformAxis.PositiveY;
                        }
                    }
                    else if (_sharedHotkeys.SwitchToZAlignmentAxis.IsActive())
                    {
                        if (currentAxis == TransformAxis.PositiveZ)
                        {
                            SharedSettings.AlignmentAxis = TransformAxis.NegativeZ;
                        }
                        else
                        {
                            SharedSettings.AlignmentAxis = TransformAxis.PositiveZ;
                        }
                    }
                }

                if (_state != State.ActiveOffsetFromAnchor &&
                    _state != State.ActiveRotateAroundAnchor)
                {
                    if (!IdentifyGrabSurface())
                    {
                        return;
                    }
                }

                if ((oldState == State.ActiveOffsetFromAnchor && _state != State.ActiveOffsetFromAnchor) ||
                    (oldState == State.ActiveRotateAroundAnchor && _state != State.ActiveRotateAroundAnchor))
                {
                    CalculateGrabTargetsAnchorVectors();
                }

                if (InputDeviceManager.Get.MouseDelta.magnitude > 0.0f)
                {
                    if (_state == State.ActiveOffsetFromAnchor)
                    {
                        OffsetTargetsFromAnchor();
                    }
                    else if (_state == State.ActiveAnchorAdjust)
                    {
                        CalculateGrabTargetsAnchorVectors();
                    }
                    else if (_state == State.ActiveSnapToSurface)
                    {
                        SnapTargetsToSurface();
                    }
                    else if (_state == State.ActiveRotate)
                    {
                        RotateTargets();
                    }
                    else if (_state == State.ActiveRotateAroundAnchor)
                    {
                        RotateTargetsAroundAnchor();
                    }
                    else if (_state == State.ActiveScale)
                    {
                        ScaleTargets();
                    }
                    else if (_state == State.ActiveOffsetFromSurface)
                    {
                        OffsetTargetsFromSurface();
                    }
                }
            }
        }
コード例 #21
0
 public static Vector3 GetGlobalVector(TransformAxis axis)
 {
     return(_globalVectors[(int)axis]);
 }
コード例 #22
0
        public static Quaternion Align(this Transform transform, Vector3 normAlignVector, TransformAxis alignmentAxis)
        {
            Vector3 axis = transform.up;

            if (alignmentAxis != TransformAxis.PositiveY)
            {
                if (alignmentAxis == TransformAxis.PositiveX)
                {
                    axis = transform.right;
                }
                else if (alignmentAxis == TransformAxis.NegativeX)
                {
                    axis = -transform.right;
                }
                else if (alignmentAxis == TransformAxis.NegativeY)
                {
                    axis = -transform.up;
                }
                else if (alignmentAxis == TransformAxis.PositiveZ)
                {
                    axis = transform.forward;
                }
                else if (alignmentAxis == TransformAxis.NegativeZ)
                {
                    axis = -transform.forward;
                }
            }

            float alignment = Vector3.Dot(axis, normAlignVector);

            if (1.0f - alignment < 1e-5f)
            {
                return(Quaternion.identity);
            }

            Vector3 rotAxis = Vector3.zero;

            // Check if the alignment axis is aligned with the alignment vector in the opposite direction
            if (alignment + 1.0f < 1e-5f)
            {
                if (alignmentAxis == TransformAxis.PositiveX)
                {
                    rotAxis = transform.up;
                }
                else if (alignmentAxis == TransformAxis.NegativeX)
                {
                    rotAxis = -transform.up;
                }
                else if (alignmentAxis == TransformAxis.PositiveY)
                {
                    rotAxis = transform.right;
                }
                else if (alignmentAxis == TransformAxis.NegativeY)
                {
                    rotAxis = -transform.right;
                }
                else if (alignmentAxis == TransformAxis.PositiveZ)
                {
                    rotAxis = transform.up;
                }
                else if (alignmentAxis == TransformAxis.NegativeZ)
                {
                    rotAxis = -transform.up;
                }
            }
            else
            {
                rotAxis = Vector3.Normalize(Vector3.Cross(axis, normAlignVector));
            }

            float rotAngle = Vector3Ex.SignedAngle(axis, normAlignVector, rotAxis);

            transform.Rotate(rotAxis, rotAngle, Space.World);
            return(Quaternion.AngleAxis(rotAngle, rotAxis));
        }
コード例 #23
0
        private static void RandomizeRotationForAxis(Transform objectTransform, TransformAxis axis, AxisRotationRandomizationModeSettings rotationRandomizationModeSettings)
        {
            Vector3 axisVector = TransformAxes.GetVector(axis, TransformSpace.Global, objectTransform);

            RandomizeRotationForAxis(objectTransform, axisVector, rotationRandomizationModeSettings);
        }
コード例 #24
0
    void Update()
    {
        if (Input.touchCount == 0)
        {
            if (currentTouchOperation == TouchOperation.SELECT)
            {
                voxelArray.TouchUp();
            }
            if (currentTouchOperation == TouchOperation.MOVE)
            {
                movingAxis.TouchUp();
            }
            currentTouchOperation = TouchOperation.NONE;
        }
        else if (Input.touchCount == 1)
        {
            Touch touch = Input.GetTouch(0);

            RaycastHit hit;
            if (currentTouchOperation != TouchOperation.SELECT)
            {
                selectingXRay = true;
            }
            bool rayHitSomething = Physics.Raycast(cam.ScreenPointToRay(Input.GetTouch(0).position),
                                                   out hit, Mathf.Infinity, selectingXRay ? Physics.DefaultRaycastLayers : NO_XRAY_MASK);
            Voxel         hitVoxel         = null;
            int           hitFaceI         = -1;
            TransformAxis hitTransformAxis = null;
            ObjectMarker  hitMarker        = null;
            if (rayHitSomething)
            {
                GameObject hitObject = hit.transform.gameObject;
                if (hitObject.tag == "Voxel")
                {
                    hitVoxel = hitObject.GetComponent <Voxel>();
                    hitFaceI = Voxel.FaceIForDirection(hit.normal);
                    if (hitFaceI == -1)
                    {
                        hitVoxel = null;
                    }
                }
                else if (hitObject.tag == "ObjectMarker")
                {
                    hitMarker = hitObject.GetComponent <ObjectMarker>();
                }
                else if (hitObject.tag == "MoveAxis")
                {
                    hitTransformAxis = hitObject.GetComponent <TransformAxis>();
                }

                if ((hitVoxel != null && hitVoxel.substance != null && hitVoxel.substance.xRay) ||
                    (hitMarker != null && (hitMarker.gameObject.layer == 8 || hitMarker.gameObject.layer == 10)))     // xray or SelectedObject layer
                {
                    // allow moving axes through xray substances
                    RaycastHit newHit;
                    if (Physics.Raycast(cam.ScreenPointToRay(Input.GetTouch(0).position),
                                        out newHit, Mathf.Infinity, NO_TRANSPARENT_MASK))
                    {
                        if (newHit.transform.tag == "MoveAxis")
                        {
                            hitVoxel         = null;
                            hitFaceI         = -1;
                            hitMarker        = null;
                            hitTransformAxis = newHit.transform.GetComponent <TransformAxis>();
                        }
                    }
                }
            }
            if (hitVoxel != null)
            {
                lastHitVoxel = hitVoxel;
                lastHitFaceI = hitFaceI;
            }
            else if (hitMarker != null)
            {
                lastHitVoxel = null;
                lastHitFaceI = -1;
            }

            if (touch.phase == TouchPhase.Began)
            {
                if (currentTouchOperation == TouchOperation.SELECT)
                {
                    voxelArray.TouchUp();
                }
                // this seems to improve the reliability of double-taps when things are running slowly.
                // I think it's because there's not always a long enough gap between taps
                // for the touch operation to be cleared.
                currentTouchOperation = TouchOperation.NONE;
            }

            if (currentTouchOperation == TouchOperation.NONE)
            {
                if (GUIPanel.PanelContainingPoint(touch.position) != null)
                {
                    currentTouchOperation = TouchOperation.GUI;
                }
                else if (touch.phase != TouchPhase.Moved && touch.phase != TouchPhase.Ended && touch.tapCount == 1)
                {
                }   // wait until moved or released, in case a multitouch operation is about to begin
                else if (!rayHitSomething)
                {
                    voxelArray.TouchDown(null);
                }
                else if (hitVoxel != null)
                {
                    if (touch.tapCount == 1)
                    {
                        currentTouchOperation = TouchOperation.SELECT;
                        voxelArray.TouchDown(hitVoxel, hitFaceI);
                        selectingXRay = hitVoxel.substance != null && hitVoxel.substance.xRay;
                    }
                    else if (touch.tapCount == 2)
                    {
                        voxelArray.DoubleTouch(hitVoxel, hitFaceI);
                    }
                    else if (touch.tapCount == 3)
                    {
                        voxelArray.TripleTouch(hitVoxel, hitFaceI);
                    }
                    UpdateZoomDepth();
                }
                else if (hitMarker != null)
                {
                    currentTouchOperation = TouchOperation.SELECT;
                    voxelArray.TouchDown(hitMarker);
                    selectingXRay = hitMarker.objectEntity.xRay;
                    UpdateZoomDepth();
                }
                else if (hitTransformAxis != null)
                {
                    if (touch.tapCount == 1)
                    {
                        currentTouchOperation = TouchOperation.MOVE;
                        movingAxis            = hitTransformAxis;
                        movingAxis.TouchDown(touch);
                    }
                    else if (touch.tapCount == 2 && lastHitVoxel != null)
                    {
                        voxelArray.DoubleTouch(lastHitVoxel, lastHitFaceI);
                    }
                    else if (touch.tapCount == 3 && lastHitVoxel != null)
                    {
                        voxelArray.TripleTouch(lastHitVoxel, lastHitFaceI);
                    }
                    UpdateZoomDepth();
                }
            } // end if currentTouchOperation == NONE

            else if (currentTouchOperation == TouchOperation.SELECT)
            {
                if (hitVoxel != null)
                {
                    voxelArray.TouchDrag(hitVoxel, hitFaceI);
                }
                if (hitMarker != null)
                {
                    voxelArray.TouchDrag(hitMarker);
                }
            }
            else if (currentTouchOperation == TouchOperation.MOVE)
            {
                movingAxis.TouchDrag(touch);
            }
        } // end if touch count is 1
        else if (Input.touchCount == 2)
        {
            if (currentTouchOperation == TouchOperation.NONE)
            {
                currentTouchOperation = TouchOperation.CAMERA;
                UpdateZoomDepth();
            }
            if (currentTouchOperation != TouchOperation.CAMERA)
            {
                return;
            }

            Touch touchZero = Input.GetTouch(0);
            Touch touchOne  = Input.GetTouch(1);

            Vector2 touchZeroPrevPos = touchZero.position - touchZero.deltaPosition;
            Vector2 touchOnePrevPos  = touchOne.position - touchOne.deltaPosition;

            float prevTouchDeltaMag = (touchZeroPrevPos - touchOnePrevPos).magnitude;
            float touchDeltaMag     = (touchZero.position - touchOne.position).magnitude;

            float deltaMagnitudeDiff = prevTouchDeltaMag - touchDeltaMag;

            float scaleFactor = Mathf.Pow(1.005f, deltaMagnitudeDiff / cam.pixelHeight * 700f);
            if (scaleFactor != 1)
            {
                pivot.localScale *= scaleFactor;
                if (pivot.localScale.x > MAX_ZOOM)
                {
                    pivot.localScale = new Vector3(MAX_ZOOM, MAX_ZOOM, MAX_ZOOM);
                }
                if (pivot.localScale.x < MIN_ZOOM)
                {
                    pivot.localScale = new Vector3(MIN_ZOOM, MIN_ZOOM, MIN_ZOOM);
                }
            }

            Vector3 move = (touchZero.deltaPosition + touchOne.deltaPosition) / 2;
            move *= 300f;
            move /= cam.pixelHeight;
            Vector3 pivotRotationEuler = pivot.rotation.eulerAngles;
            pivotRotationEuler.y += move.x;
            pivotRotationEuler.x -= move.y;
            if (pivotRotationEuler.x > 90 && pivotRotationEuler.x < 180)
            {
                pivotRotationEuler.x = 90;
            }
            if (pivotRotationEuler.x < -90 || (pivotRotationEuler.x > 180 && pivotRotationEuler.x < 270))
            {
                pivotRotationEuler.x = -90;
            }
            pivot.rotation = Quaternion.Euler(pivotRotationEuler);
        }
        else if (Input.touchCount == 3)
        {
            if (currentTouchOperation == TouchOperation.NONE)
            {
                currentTouchOperation = TouchOperation.CAMERA;
                UpdateZoomDepth();
            }
            if (currentTouchOperation != TouchOperation.CAMERA)
            {
                return;
            }

            Vector2 move = new Vector2(0, 0);
            for (int i = 0; i < 3; i++)
            {
                move += Input.GetTouch(i).deltaPosition;
            }
            move           *= 4.0f;
            move           /= cam.pixelHeight;
            pivot.position -= move.x * pivot.right * pivot.localScale.z;
            pivot.position -= move.y * pivot.up * pivot.localScale.z;
        }
    }