blob: b4eb1c2c9f6d8f25f0dc3f5c5016dab6ab6f6d03 [file] [log] [blame]
package com.cooliris.media;
public final class GridCameraManager {
private final GridCamera mCamera;
private static final Pool<Vector3f> sPool;
static {
final Vector3f[] vectorPool = new Vector3f[128];
int length = vectorPool.length;
for (int i = 0; i < length; ++i) {
vectorPool[i] = new Vector3f();
}
sPool = new Pool<Vector3f>(vectorPool);
}
public GridCameraManager(final GridCamera camera) {
mCamera = camera;
}
public void centerCameraForSlot(LayoutInterface layout, int slotIndex, float baseConvergence, Vector3f deltaAnchorPositionIn,
int selectedSlotIndex, float zoomValue, float imageTheta, int state) {
final GridCamera camera = mCamera;
final Pool<Vector3f> pool = sPool;
synchronized (camera) {
final boolean zoomin = (selectedSlotIndex != Shared.INVALID);
final int theta = (int) imageTheta;
final int portrait = (theta / 90) % 2;
if (slotIndex == selectedSlotIndex) {
camera.mConvergenceSpeed = baseConvergence * (zoomin ? 2.0f : 2.0f);
}
final float oneByZoom = 1.0f / zoomValue;
if (slotIndex >= 0) {
final Vector3f position = pool.create();
final Vector3f deltaAnchorPosition = pool.create();
try {
deltaAnchorPosition.set(deltaAnchorPositionIn);
GridCameraManager.getSlotPositionForSlotIndex(slotIndex, camera, layout, deltaAnchorPosition, position);
position.x = (zoomValue == 1.0f) ? ((position.x) * camera.mOneByScale) : camera.mLookAtX;
position.y = (zoomValue == 1.0f) ? 0 : camera.mLookAtY;
if (state == GridLayer.STATE_MEDIA_SETS || state == GridLayer.STATE_TIMELINE) {
position.y = -0.1f;
}
float width = camera.mItemWidth;
float height = camera.mItemHeight;
if (portrait != 0) {
float temp = width;
width = height;
height = temp;
}
camera.moveTo(position.x, position.y, zoomin ? camera.getDistanceToFitRect(width * oneByZoom, height * oneByZoom) : 0);
} finally {
pool.delete(position);
pool.delete(deltaAnchorPosition);
}
} else {
camera.moveYTo(0);
camera.moveZTo(0);
}
}
}
// CR: line too long. Documentation--what are the semantics of the return value?
/**
*/
public boolean constrainCameraForSlot(LayoutInterface layout, int slotIndex, Vector3f deltaAnchorPositionIn,
float currentFocusItemWidth, float currentFocusItemHeight) {
final GridCamera camera = mCamera;
final Pool<Vector3f> pool = sPool;
boolean retVal = false;
synchronized (camera) {
final Vector3f position = pool.create();
final Vector3f deltaAnchorPosition = pool.create();
final Vector3f topLeft = pool.create();
final Vector3f bottomRight = pool.create();
final Vector3f imgTopLeft = pool.create();
final Vector3f imgBottomRight = pool.create();
try {
if (slotIndex >= 0) {
deltaAnchorPosition.set(deltaAnchorPositionIn);
GridCameraManager.getSlotPositionForSlotIndex(slotIndex, camera, layout, deltaAnchorPosition, position);
position.x *= camera.mOneByScale;
position.y = 0.0f;
float width = (currentFocusItemWidth / 2);
float height = (currentFocusItemHeight / 2);
imgTopLeft.set(position.x - width, position.y - height, 0);
imgBottomRight.set(position.x + width, position.y + height, 0);
camera.convertToCameraSpace(0, 0, 0, topLeft);
camera.convertToCameraSpace(camera.mWidth, camera.mHeight, 0, bottomRight);
float leftExtent = topLeft.x - imgTopLeft.x;
float rightExtent = bottomRight.x - imgBottomRight.x;
camera.mConvergenceSpeed = 2.0f;
if (leftExtent < 0) {
retVal = true;
camera.moveBy(-leftExtent, 0, 0);
}
if (rightExtent > 0) {
retVal = true;
camera.moveBy(-rightExtent, 0, 0);
}
float topExtent = topLeft.y - imgTopLeft.y;
float bottomExtent = bottomRight.y - imgBottomRight.y;
if (topExtent < 0) {
camera.moveBy(0, -topExtent, 0);
}
if (bottomExtent > 0) {
camera.moveBy(0, -bottomExtent, 0);
}
}
} finally {
pool.delete(position);
pool.delete(deltaAnchorPosition);
pool.delete(topLeft);
pool.delete(bottomRight);
pool.delete(imgTopLeft);
pool.delete(imgBottomRight);
}
}
return retVal;
}
public void computeVisibleRange(MediaFeed feed, LayoutInterface layout, Vector3f deltaAnchorPositionIn,
IndexRange outVisibleRange, IndexRange outBufferedVisibleRange, IndexRange outCompleteRange, int state) {
GridCamera camera = mCamera;
Pool<Vector3f> pool = sPool;
float offset = (camera.mLookAtX * camera.mScale);
int itemWidth = camera.mItemWidth;
float maxIncrement = camera.mWidth * 0.5f + itemWidth;
float left = -maxIncrement + offset;
float right = left + 2.0f * maxIncrement;
if (state == GridLayer.STATE_MEDIA_SETS || state == GridLayer.STATE_TIMELINE) {
right += (itemWidth * 0.5f);
}
float top = -maxIncrement;
float bottom = camera.mHeight + maxIncrement;
// the hint to compute the visible display items
int numSlots = 0;
if (feed != null) {
numSlots = feed.getNumSlots();
}
synchronized (outCompleteRange) {
outCompleteRange.set(0, numSlots - 1);
}
Vector3f position = pool.create();
Vector3f deltaAnchorPosition = pool.create();
try {
int firstVisibleSlotIndex = 0;
int lastVisibleSlotIndex = numSlots - 1;
int leftEdge = firstVisibleSlotIndex;
int rightEdge = lastVisibleSlotIndex;
int index = (leftEdge + rightEdge) / 2;
lastVisibleSlotIndex = firstVisibleSlotIndex;
deltaAnchorPosition.set(deltaAnchorPositionIn);
while (index != leftEdge) {
GridCameraManager.getSlotPositionForSlotIndex(index, camera, layout, deltaAnchorPosition, position);
if (FloatUtils.boundsContainsPoint(left, right, top, bottom, position.x, position.y)) {
// this index is visible
firstVisibleSlotIndex = index;
lastVisibleSlotIndex = index;
break;
} else {
if (position.x > left) {
rightEdge = index;
} else {
leftEdge = index;
}
index = (leftEdge + rightEdge) / 2;
}
}
// CR: comments would make me a happy panda.
while (firstVisibleSlotIndex >= 0 && firstVisibleSlotIndex < numSlots) {
GridCameraManager.getSlotPositionForSlotIndex(firstVisibleSlotIndex, camera, layout, deltaAnchorPosition, position);
// CR: !fubar instead of fubar == false.
if (FloatUtils.boundsContainsPoint(left, right, top, bottom, position.x, position.y) == false) {
++firstVisibleSlotIndex;
break;
} else {
--firstVisibleSlotIndex;
}
}
while (lastVisibleSlotIndex >= 0 && lastVisibleSlotIndex < numSlots) {
GridCameraManager.getSlotPositionForSlotIndex(lastVisibleSlotIndex, camera, layout, deltaAnchorPosition, position);
if (FloatUtils.boundsContainsPoint(left, right, top, bottom, position.x, position.y) == false) {
--lastVisibleSlotIndex;
break;
} else {
++lastVisibleSlotIndex;
}
}
if (firstVisibleSlotIndex < 0)
firstVisibleSlotIndex = 0;
if (lastVisibleSlotIndex >= numSlots)
lastVisibleSlotIndex = numSlots - 1;
synchronized (outVisibleRange) {
outVisibleRange.set(firstVisibleSlotIndex, lastVisibleSlotIndex);
}
if (feed != null) {
feed.setVisibleRange(firstVisibleSlotIndex, lastVisibleSlotIndex);
}
final int buffer = 24;
firstVisibleSlotIndex = ((firstVisibleSlotIndex - buffer) / buffer) * buffer;
lastVisibleSlotIndex += buffer;
lastVisibleSlotIndex = (lastVisibleSlotIndex / buffer) * buffer;
if (firstVisibleSlotIndex < 0) {
firstVisibleSlotIndex = 0;
}
if (lastVisibleSlotIndex >= numSlots) {
lastVisibleSlotIndex = numSlots - 1;
}
synchronized (outBufferedVisibleRange) {
outBufferedVisibleRange.set(firstVisibleSlotIndex, lastVisibleSlotIndex);
}
} finally {
pool.delete(position);
pool.delete(deltaAnchorPosition);
}
}
public static final void getSlotPositionForSlotIndex(int slotIndex, GridCamera camera, LayoutInterface layout,
Vector3f deltaAnchorPosition, Vector3f outVal) {
layout.getPositionForSlotIndex(slotIndex, camera.mItemWidth, camera.mItemHeight, outVal);
outVal.subtract(deltaAnchorPosition);
}
public static final float getFillScreenZoomValue(GridCamera camera, Pool<Vector3f> pool, float currentFocusItemWidth,
float currentFocusItemHeight) {
final Vector3f topLeft = pool.create();
final Vector3f bottomRight = pool.create();
float potentialZoomValue = 1.0f;
try {
camera.convertToCameraSpace(0, 0, 0, topLeft);
camera.convertToCameraSpace(camera.mWidth, camera.mHeight, 0, bottomRight);
float xExtent = Math.abs(topLeft.x - bottomRight.x) / currentFocusItemWidth;
float yExtent = Math.abs(topLeft.y - bottomRight.y) / currentFocusItemHeight;
potentialZoomValue = Math.max(xExtent, yExtent);
} finally {
pool.delete(topLeft);
pool.delete(bottomRight);
}
return potentialZoomValue;
}
}