• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
18 package com.replica.replicaisland;
19 
20 /** A sphere collision volume. */
21 public class SphereCollisionVolume extends CollisionVolume {
22     private float mRadius;
23     private Vector2 mCenter;
24     private Vector2 mWorkspaceVector;
25     private Vector2 mWorkspaceVector2;
26 
SphereCollisionVolume(float radius, float centerX, float centerY)27     public SphereCollisionVolume(float radius, float centerX, float centerY) {
28         super();
29         mRadius = radius;
30         mCenter = new Vector2(centerX, centerY);
31         mWorkspaceVector = new Vector2();
32         mWorkspaceVector2 = new Vector2();
33     }
34 
SphereCollisionVolume(float radius, float centerX, float centerY, int hit)35     public SphereCollisionVolume(float radius, float centerX, float centerY, int hit) {
36         super(hit);
37         mRadius = radius;
38         mCenter = new Vector2(centerX, centerY);
39         mWorkspaceVector = new Vector2();
40         mWorkspaceVector2 = new Vector2();
41     }
42 
43     @Override
getMaxX()44     public float getMaxX() {
45         return mCenter.x + mRadius;
46     }
47 
48     @Override
getMinX()49     public float getMinX() {
50         return mCenter.x - mRadius;
51     }
52 
53     @Override
getMaxY()54     public float getMaxY() {
55         return mCenter.y + mRadius;
56     }
57 
58     @Override
getMinY()59     public float getMinY() {
60         return mCenter.y - mRadius;
61     }
62 
getCenter()63     public Vector2 getCenter() {
64         return mCenter;
65     }
66 
setCenter(Vector2 center)67     public void setCenter(Vector2 center) {
68         mCenter.set(center);
69     }
70 
getRadius()71     public float getRadius() {
72         return mRadius;
73     }
74 
setRadius(float radius)75     public void setRadius(float radius) {
76         mRadius = radius;
77     }
78 
reset()79     public void reset() {
80         mCenter.zero();
81         mRadius = 0;
82     }
83 
84     @Override
intersects(Vector2 position, FlipInfo flip, CollisionVolume other, Vector2 otherPosition, FlipInfo otherFlip)85     public boolean intersects(Vector2 position, FlipInfo flip, CollisionVolume other,
86             Vector2 otherPosition, FlipInfo otherFlip) {
87         boolean result = false;
88 
89         if (other instanceof AABoxCollisionVolume) {
90             // It's more accurate to do a sphere-as-box test than a box-as-sphere test.
91             result = other.intersects(otherPosition, otherFlip, this, position, flip);
92         } else {
93             mWorkspaceVector.set(position);
94             offsetByCenter(mWorkspaceVector, mCenter, flip);
95 
96             float otherRadius = 0;
97             if (other instanceof SphereCollisionVolume) {
98                 SphereCollisionVolume sphereOther = (SphereCollisionVolume)other;
99                 mWorkspaceVector2.set(otherPosition);
100                 offsetByCenter(mWorkspaceVector2, sphereOther.getCenter(), otherFlip);
101                 mWorkspaceVector.subtract(mWorkspaceVector2);
102                 otherRadius = sphereOther.getRadius();
103             } else {
104                 // Whatever this volume is, pretend it's a sphere.
105                 final float deltaX = other.getMaxXPosition(otherFlip)
106                     - other.getMinXPosition(otherFlip);
107                 final float deltaY = other.getMaxYPosition(otherFlip)
108                     - other.getMinYPosition(otherFlip);
109                 final float centerX = deltaX / 2.0f;
110                 final float centerY = deltaY / 2.0f;
111 
112                 mWorkspaceVector2.set(otherPosition);
113                 mWorkspaceVector2.x += centerX;
114                 mWorkspaceVector2.y += centerY;
115                 otherRadius = Math.max(deltaX, deltaY);
116             }
117 
118             final float maxDistance = mRadius + otherRadius;
119             final float distance2 = mWorkspaceVector.length2();
120             final float maxDistance2 = (maxDistance * maxDistance);
121             if (distance2 < maxDistance2) {
122                 result = true;
123             }
124         }
125 
126         return result;
127     }
128 
growBy(CollisionVolume other)129     public void growBy(CollisionVolume other) {
130         final float maxX;
131         final float minX;
132 
133         final float maxY;
134         final float minY;
135 
136         if (mRadius > 0) {
137             maxX = Math.max(getMaxX(), other.getMaxX());
138             minX = Math.min(getMinX(), other.getMinX());
139             maxY = Math.max(getMaxY(), other.getMaxY());
140             minY = Math.min(getMinY(), other.getMinY());
141         } else {
142             maxX = other.getMaxX();
143             minX = other.getMinX();
144             maxY = other.getMaxY();
145             minY = other.getMinY();
146         }
147         final float horizontalDelta = maxX - minX;
148         final float verticalDelta = maxY - minY;
149         final float diameter = Math.max(horizontalDelta, verticalDelta);
150 
151         final float newCenterX = minX + (horizontalDelta / 2.0f);
152         final float newCenterY = minY + (verticalDelta / 2.0f);
153         final float newRadius = diameter / 2.0f;
154 
155         mCenter.set(newCenterX, newCenterY);
156         mRadius = newRadius;
157     }
158 
offsetByCenter(Vector2 position, Vector2 center, FlipInfo flip)159     private static void offsetByCenter(Vector2 position, Vector2 center, FlipInfo flip) {
160         if (flip != null && (flip.flipX || flip.flipY)) {
161             if (flip.flipX) {
162                 position.x += flip.parentWidth - center.x;
163             } else {
164                 position.x += center.x;
165             }
166 
167             if (flip.flipY) {
168                 position.y += flip.parentHeight - center.y;
169             } else {
170                 position.y += center.y;
171             }
172         } else {
173             position.add(center);
174         }
175     }
176 
177 }
178