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