1*5eae8ebbSCole Faust /* 2*5eae8ebbSCole Faust * Copyright (C) 2010 The Android Open Source Project 3*5eae8ebbSCole Faust * 4*5eae8ebbSCole Faust * Licensed under the Apache License, Version 2.0 (the "License"); 5*5eae8ebbSCole Faust * you may not use this file except in compliance with the License. 6*5eae8ebbSCole Faust * You may obtain a copy of the License at 7*5eae8ebbSCole Faust * 8*5eae8ebbSCole Faust * http://www.apache.org/licenses/LICENSE-2.0 9*5eae8ebbSCole Faust * 10*5eae8ebbSCole Faust * Unless required by applicable law or agreed to in writing, software 11*5eae8ebbSCole Faust * distributed under the License is distributed on an "AS IS" BASIS, 12*5eae8ebbSCole Faust * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*5eae8ebbSCole Faust * See the License for the specific language governing permissions and 14*5eae8ebbSCole Faust * limitations under the License. 15*5eae8ebbSCole Faust */ 16*5eae8ebbSCole Faust 17*5eae8ebbSCole Faust package com.replica.replicaisland; 18*5eae8ebbSCole Faust 19*5eae8ebbSCole Faust /** 20*5eae8ebbSCole Faust * An Axis-Aligned rectangular collision volume. This code treats other volumes as if they are 21*5eae8ebbSCole Faust * also rectangles when calculating intersections. Therefore certain types of intersections, such 22*5eae8ebbSCole Faust * as sphere vs rectangle, may not be absolutely precise (in the case of a sphere vs a rectangle, 23*5eae8ebbSCole Faust * for example, a new rectangle that fits the sphere is used to perform the intersection test, so 24*5eae8ebbSCole Faust * there is some potential for false-positives at the corners). However, for our purposes absolute 25*5eae8ebbSCole Faust * precision isn't necessary, so this simple implementation is sufficient. 26*5eae8ebbSCole Faust */ 27*5eae8ebbSCole Faust public class AABoxCollisionVolume extends CollisionVolume { 28*5eae8ebbSCole Faust private Vector2 mWidthHeight; 29*5eae8ebbSCole Faust private Vector2 mBottomLeft; 30*5eae8ebbSCole Faust AABoxCollisionVolume(float offsetX, float offsetY, float width, float height)31*5eae8ebbSCole Faust public AABoxCollisionVolume(float offsetX, float offsetY, float width, float height) { 32*5eae8ebbSCole Faust super(); 33*5eae8ebbSCole Faust mBottomLeft = new Vector2(offsetX, offsetY); 34*5eae8ebbSCole Faust mWidthHeight = new Vector2(width, height); 35*5eae8ebbSCole Faust } 36*5eae8ebbSCole Faust AABoxCollisionVolume(float offsetX, float offsetY, float width, float height, int hit)37*5eae8ebbSCole Faust public AABoxCollisionVolume(float offsetX, float offsetY, float width, float height, 38*5eae8ebbSCole Faust int hit) { 39*5eae8ebbSCole Faust super(hit); 40*5eae8ebbSCole Faust mBottomLeft = new Vector2(offsetX, offsetY); 41*5eae8ebbSCole Faust mWidthHeight = new Vector2(width, height); 42*5eae8ebbSCole Faust } 43*5eae8ebbSCole Faust 44*5eae8ebbSCole Faust @Override getMaxX()45*5eae8ebbSCole Faust public final float getMaxX() { 46*5eae8ebbSCole Faust return mBottomLeft.x + mWidthHeight.x; 47*5eae8ebbSCole Faust } 48*5eae8ebbSCole Faust 49*5eae8ebbSCole Faust @Override getMinX()50*5eae8ebbSCole Faust public final float getMinX() { 51*5eae8ebbSCole Faust return mBottomLeft.x; 52*5eae8ebbSCole Faust } 53*5eae8ebbSCole Faust 54*5eae8ebbSCole Faust @Override getMaxY()55*5eae8ebbSCole Faust public final float getMaxY() { 56*5eae8ebbSCole Faust return mBottomLeft.y + mWidthHeight.y; 57*5eae8ebbSCole Faust } 58*5eae8ebbSCole Faust 59*5eae8ebbSCole Faust @Override getMinY()60*5eae8ebbSCole Faust public final float getMinY() { 61*5eae8ebbSCole Faust return mBottomLeft.y; 62*5eae8ebbSCole Faust } 63*5eae8ebbSCole Faust 64*5eae8ebbSCole Faust /** 65*5eae8ebbSCole Faust * Calculates the intersection of this volume and another, and returns true if the 66*5eae8ebbSCole Faust * volumes intersect. This test treats the other volume as an AABox. 67*5eae8ebbSCole Faust * @param position The world position of this volume. 68*5eae8ebbSCole Faust * @param other The volume to test for intersections. 69*5eae8ebbSCole Faust * @param otherPosition The world position of the other volume. 70*5eae8ebbSCole Faust * @return true if the volumes overlap, false otherwise. 71*5eae8ebbSCole Faust */ 72*5eae8ebbSCole Faust @Override intersects(Vector2 position, FlipInfo flip, CollisionVolume other, Vector2 otherPosition, FlipInfo otherFlip)73*5eae8ebbSCole Faust public boolean intersects(Vector2 position, FlipInfo flip, CollisionVolume other, 74*5eae8ebbSCole Faust Vector2 otherPosition, FlipInfo otherFlip) { 75*5eae8ebbSCole Faust final float left = getMinXPosition(flip) + position.x; 76*5eae8ebbSCole Faust final float right = getMaxXPosition(flip) + position.x; 77*5eae8ebbSCole Faust final float bottom = getMinYPosition(flip) + position.y; 78*5eae8ebbSCole Faust final float top = getMaxYPosition(flip) + position.y; 79*5eae8ebbSCole Faust 80*5eae8ebbSCole Faust final float otherLeft = other.getMinXPosition(otherFlip) + otherPosition.x; 81*5eae8ebbSCole Faust final float otherRight = other.getMaxXPosition(otherFlip) + otherPosition.x; 82*5eae8ebbSCole Faust final float otherBottom = other.getMinYPosition(otherFlip) + otherPosition.y; 83*5eae8ebbSCole Faust final float otherTop = other.getMaxYPosition(otherFlip) + otherPosition.y; 84*5eae8ebbSCole Faust 85*5eae8ebbSCole Faust final boolean result = boxIntersect(left, right, top, bottom, 86*5eae8ebbSCole Faust otherLeft, otherRight, otherTop, otherBottom) 87*5eae8ebbSCole Faust || boxIntersect(otherLeft, otherRight, otherTop, otherBottom, 88*5eae8ebbSCole Faust left, right, top, bottom); 89*5eae8ebbSCole Faust 90*5eae8ebbSCole Faust return result; 91*5eae8ebbSCole Faust } 92*5eae8ebbSCole Faust 93*5eae8ebbSCole Faust /** Tests two axis-aligned boxes for overlap. */ boxIntersect(float left1, float right1, float top1, float bottom1, float left2, float right2, float top2, float bottom2)94*5eae8ebbSCole Faust private boolean boxIntersect(float left1, float right1, float top1, float bottom1, 95*5eae8ebbSCole Faust float left2, float right2, float top2, float bottom2) { 96*5eae8ebbSCole Faust final boolean horizontalIntersection = left1 < right2 && left2 < right1; 97*5eae8ebbSCole Faust final boolean verticalIntersection = top1 > bottom2 && top2 > bottom1; 98*5eae8ebbSCole Faust final boolean intersecting = horizontalIntersection && verticalIntersection; 99*5eae8ebbSCole Faust return intersecting; 100*5eae8ebbSCole Faust } 101*5eae8ebbSCole Faust 102*5eae8ebbSCole Faust /** Increases the size of this volume as necessary to fit the passed volume. */ growBy(CollisionVolume other)103*5eae8ebbSCole Faust public void growBy(CollisionVolume other) { 104*5eae8ebbSCole Faust final float maxX; 105*5eae8ebbSCole Faust final float minX; 106*5eae8ebbSCole Faust 107*5eae8ebbSCole Faust final float maxY; 108*5eae8ebbSCole Faust final float minY; 109*5eae8ebbSCole Faust 110*5eae8ebbSCole Faust if (mWidthHeight.length2() > 0) { 111*5eae8ebbSCole Faust maxX = Math.max(getMaxX(), other.getMaxX()); 112*5eae8ebbSCole Faust minX = Math.max(getMinX(), other.getMinX()); 113*5eae8ebbSCole Faust maxY = Math.max(getMaxY(), other.getMaxY()); 114*5eae8ebbSCole Faust minY = Math.max(getMinY(), other.getMinY()); 115*5eae8ebbSCole Faust } else { 116*5eae8ebbSCole Faust maxX = other.getMaxX(); 117*5eae8ebbSCole Faust minX = other.getMinX(); 118*5eae8ebbSCole Faust maxY = other.getMaxY(); 119*5eae8ebbSCole Faust minY = other.getMinY(); 120*5eae8ebbSCole Faust } 121*5eae8ebbSCole Faust final float horizontalDelta = maxX - minX; 122*5eae8ebbSCole Faust final float verticalDelta = maxY - minY; 123*5eae8ebbSCole Faust mBottomLeft.set(minX, minY); 124*5eae8ebbSCole Faust mWidthHeight.set(horizontalDelta, verticalDelta); 125*5eae8ebbSCole Faust } 126*5eae8ebbSCole Faust 127*5eae8ebbSCole Faust } 128