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 17 package 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 */ 27 public class AABoxCollisionVolume extends CollisionVolume { 28 private Vector2 mWidthHeight; 29 private Vector2 mBottomLeft; 30 AABoxCollisionVolume(float offsetX, float offsetY, float width, float height)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 AABoxCollisionVolume(float offsetX, float offsetY, float width, float height, int hit)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 getMaxX()45 public final float getMaxX() { 46 return mBottomLeft.x + mWidthHeight.x; 47 } 48 49 @Override getMinX()50 public final float getMinX() { 51 return mBottomLeft.x; 52 } 53 54 @Override getMaxY()55 public final float getMaxY() { 56 return mBottomLeft.y + mWidthHeight.y; 57 } 58 59 @Override getMinY()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 intersects(Vector2 position, FlipInfo flip, CollisionVolume other, Vector2 otherPosition, FlipInfo otherFlip)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. */ boxIntersect(float left1, float right1, float top1, float bottom1, float left2, float right2, float top2, float bottom2)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. */ growBy(CollisionVolume other)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