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