@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; }