@Override
  public boolean onTouch(View v, MotionEvent event) {
    // x and y coordinates of touch location on screen.
    float x = event.getX();
    float y = event.getY();

    switch (event.getAction()) {
      case MotionEvent.ACTION_DOWN:
        // Initial pointer down
        mode = LOOK;

        Vector3d near = unProject(x, y, 0, mMVPMatrix, this.width, this.height);
        Vector3d far = unProject(x, y, 1, mMVPMatrix, this.width, this.height);
        Vector3d pickingRay = far.subtract(near);
        Vector3d normal = new Vector3d(0, 0, 1);
        if (normal.dot(pickingRay) != 0 && pickingRay.z < 0) {
          Vector3d diff = new Vector3d(-totalDiffX, -totalDiffY, 0);
          float t = (-2f - normal.dot(diff)) / (normal.dot(pickingRay));
          pickingRay = diff.add(pickingRay.scale(t));
          boolean b = false;
          synchronized (this.objects) {
            int counter = 0; // counter for checking current position.
            List<Integer> positions =
                new ArrayList<
                    Integer>(); // array for storing object array positions that you've "touched"
            for (Prim p : this.objects) {
              Vector3d objectCenter = p.getCenter();
              float d =
                  (((objectCenter.subtract(near)).cross(objectCenter.subtract(far))).length())
                      / ((far.subtract(near)).length());
              if (d < p.getSize().x || d < p.getSize().y || d < p.getSize().z) {
                positions.add(
                    counter); // add position value to array for checking if closest to camera than
                              // others you touched.
                b =
                    true; // stops from creating new objects so you don't erase and create at the
                          // same time.
              }
              counter++;
            }
            if (positions.size() > 0) {
              Vector3d currentCenter; // variable where current center will be stored.
              currentCenter =
                  objects
                      .get(positions.get(0))
                      .getCenter(); // get the first center for distance checking
              double minDistance =
                  Math.sqrt(
                      (double)
                          (Math.pow((double) currentCenter.x - totalDiffX, 2.0)
                              + Math.pow((double) currentCenter.y - totalDiffY, 2.0)
                              + Math.pow(
                                  (double) currentCenter.z,
                                  2.0))); // distance formula of the first position. the first
                                          // position is initially set as the smallest.
              int finalMin =
                  0; // int value where the smallest distance position is stored for removal
              for (int i = 1;
                  i < positions.size();
                  i++) // starting at one because 0 was already checked before the loop
              {
                currentCenter =
                    objects
                        .get(positions.get(i))
                        .getCenter(); // get the current center of the object for testing distance.
                double currentDistance =
                    Math.sqrt(
                        (double)
                            (Math.pow((double) currentCenter.x - totalDiffX, 2.0)
                                + Math.pow((double) currentCenter.y - totalDiffY, 2.0)
                                + Math.pow(
                                    (double) currentCenter.z,
                                    2.0))); // distance formula for the current position. This is
                                            // tested to see if smaller than the one before it.
                if (currentDistance < minDistance) {
                  minDistance =
                      currentDistance; // min becomes the current because current is smaller
                  finalMin = i; // current position is stored as smallest distance position.
                }
              }
              this.objects.remove(
                  (int) positions.get(finalMin)); // remove object closest to camera that you touch.
            }
            counter = 0;
          }
          if (b == false
              && pickingRay.x < 254.75
              && pickingRay.x > .25
              && pickingRay.y > .25
              && pickingRay.y < 254.75) {
            addObject(pickingRay.x, pickingRay.y, pickingRay.z + .25f, Shape.BOX);
          }
        }
        break;
      case MotionEvent.ACTION_POINTER_DOWN:
        // non-primary pointer down
        oldDist = spacing(event);
        // check distance as one finger may be reported as multiple ones very close together
        if (oldDist > 10f) {
          mode = ZOOM;
        }

        break;
      case MotionEvent.ACTION_MOVE:
        if (event.getPointerCount() >= 2 && this.mode != ZOOM) {
          oldDist = spacing(event);
          // check distance as one finger may be reported as multiple ones very close together
          if (oldDist > 10f) {
            mode = ZOOM;
          }
        }
        if (mode == ZOOM) {
          float newDist = spacing(event);
          float diff = newDist - oldDist;
          if (newDist > 10f && Math.abs(diff) > 20f) {
            Vector3d lookAtVector = this.mCamera.look.subtract(this.mCamera.eye);
            lookAtVector = lookAtVector.normalize();
            lookAtVector = lookAtVector.scale(diff * .00025f);
            this.diffX -= lookAtVector.x;
            this.diffY -= lookAtVector.y;
          }

        } else if (mode == LOOK) {
          float dx = x - mPreviousX;
          float dy = y - mPreviousY;
          this.dx = dx * .008f;
          this.dy = dy * .008f;

          updateLookAt();
        }
        break;

      case MotionEvent.ACTION_POINTER_UP:
        if (event.getPointerCount() == 1) {
          mode = LOOK;
        }

      case MotionEvent.ACTION_UP:
        mode = NONE;
        break;
    }
    mPreviousX = x;
    mPreviousY = y;
    return true;
  }