xref: /aosp_15_r20/external/replicaisland/src/com/replica/replicaisland/AABoxCollisionVolume.java (revision 5eae8ebb3c5756e41e77a1f7201fcf94b0eade1f)
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