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