/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.replica.replicaisland; /** A sphere collision volume. */ public class SphereCollisionVolume extends CollisionVolume { private float mRadius; private Vector2 mCenter; private Vector2 mWorkspaceVector; private Vector2 mWorkspaceVector2; public SphereCollisionVolume(float radius, float centerX, float centerY) { super(); mRadius = radius; mCenter = new Vector2(centerX, centerY); mWorkspaceVector = new Vector2(); mWorkspaceVector2 = new Vector2(); } public SphereCollisionVolume(float radius, float centerX, float centerY, int hit) { super(hit); mRadius = radius; mCenter = new Vector2(centerX, centerY); mWorkspaceVector = new Vector2(); mWorkspaceVector2 = new Vector2(); } @Override public float getMaxX() { return mCenter.x + mRadius; } @Override public float getMinX() { return mCenter.x - mRadius; } @Override public float getMaxY() { return mCenter.y + mRadius; } @Override public float getMinY() { return mCenter.y - mRadius; } public Vector2 getCenter() { return mCenter; } public void setCenter(Vector2 center) { mCenter.set(center); } public float getRadius() { return mRadius; } public void setRadius(float radius) { mRadius = radius; } public void reset() { mCenter.zero(); mRadius = 0; } @Override public boolean intersects(Vector2 position, FlipInfo flip, CollisionVolume other, Vector2 otherPosition, FlipInfo otherFlip) { boolean result = false; if (other instanceof AABoxCollisionVolume) { // It's more accurate to do a sphere-as-box test than a box-as-sphere test. result = other.intersects(otherPosition, otherFlip, this, position, flip); } else { mWorkspaceVector.set(position); offsetByCenter(mWorkspaceVector, mCenter, flip); float otherRadius = 0; if (other instanceof SphereCollisionVolume) { SphereCollisionVolume sphereOther = (SphereCollisionVolume)other; mWorkspaceVector2.set(otherPosition); offsetByCenter(mWorkspaceVector2, sphereOther.getCenter(), otherFlip); mWorkspaceVector.subtract(mWorkspaceVector2); otherRadius = sphereOther.getRadius(); } else { // Whatever this volume is, pretend it's a sphere. final float deltaX = other.getMaxXPosition(otherFlip) - other.getMinXPosition(otherFlip); final float deltaY = other.getMaxYPosition(otherFlip) - other.getMinYPosition(otherFlip); final float centerX = deltaX / 2.0f; final float centerY = deltaY / 2.0f; mWorkspaceVector2.set(otherPosition); mWorkspaceVector2.x += centerX; mWorkspaceVector2.y += centerY; otherRadius = Math.max(deltaX, deltaY); } final float maxDistance = mRadius + otherRadius; final float distance2 = mWorkspaceVector.length2(); final float maxDistance2 = (maxDistance * maxDistance); if (distance2 < maxDistance2) { result = true; } } return result; } public void growBy(CollisionVolume other) { final float maxX; final float minX; final float maxY; final float minY; if (mRadius > 0) { maxX = Math.max(getMaxX(), other.getMaxX()); minX = Math.min(getMinX(), other.getMinX()); maxY = Math.max(getMaxY(), other.getMaxY()); minY = Math.min(getMinY(), other.getMinY()); } else { maxX = other.getMaxX(); minX = other.getMinX(); maxY = other.getMaxY(); minY = other.getMinY(); } final float horizontalDelta = maxX - minX; final float verticalDelta = maxY - minY; final float diameter = Math.max(horizontalDelta, verticalDelta); final float newCenterX = minX + (horizontalDelta / 2.0f); final float newCenterY = minY + (verticalDelta / 2.0f); final float newRadius = diameter / 2.0f; mCenter.set(newCenterX, newCenterY); mRadius = newRadius; } private static void offsetByCenter(Vector2 position, Vector2 center, FlipInfo flip) { if (flip != null && (flip.flipX || flip.flipY)) { if (flip.flipX) { position.x += flip.parentWidth - center.x; } else { position.x += center.x; } if (flip.flipY) { position.y += flip.parentHeight - center.y; } else { position.y += center.y; } } else { position.add(center); } } }