OSDN Git Service

Updates to 3D gallery. Build 1203.
[android-x86/packages-apps-Gallery2.git] / src / com / cooliris / media / GridCameraManager.java
1 package com.cooliris.media;
2
3
4 public final class GridCameraManager {
5     private final GridCamera mCamera;
6     private static final Pool<Vector3f> sPool;
7     static {
8         final Vector3f[] vectorPool = new Vector3f[128];
9         int length = vectorPool.length;
10         for (int i = 0; i < length; ++i) {
11             vectorPool[i] = new Vector3f();
12         }
13         sPool = new Pool<Vector3f>(vectorPool);
14     }
15
16     public GridCameraManager(final GridCamera camera) {
17         mCamera = camera;
18     }
19
20     public void centerCameraForSlot(LayoutInterface layout, int slotIndex, float baseConvergence, Vector3f deltaAnchorPositionIn,
21             int selectedSlotIndex, float zoomValue, float imageTheta, int state) {
22         final GridCamera camera = mCamera;
23         final Pool<Vector3f> pool = sPool;
24         synchronized (camera) {
25             final boolean zoomin = (selectedSlotIndex != Shared.INVALID);
26             final int theta = (int) imageTheta;
27             final int portrait = (theta / 90) % 2;
28             if (slotIndex == selectedSlotIndex) {
29                 camera.mConvergenceSpeed = baseConvergence * (zoomin ? 2.0f : 2.0f);
30             }
31             final float oneByZoom = 1.0f / zoomValue;
32             if (slotIndex >= 0) {
33                 final Vector3f position = pool.create();
34                 final Vector3f deltaAnchorPosition = pool.create();
35                 try {
36                     deltaAnchorPosition.set(deltaAnchorPositionIn);
37                     GridCameraManager.getSlotPositionForSlotIndex(slotIndex, camera, layout, deltaAnchorPosition, position);
38                     position.x = (zoomValue == 1.0f) ? ((position.x) * camera.mOneByScale) : camera.mLookAtX;
39                     position.y = (zoomValue == 1.0f) ? 0 : camera.mLookAtY;
40                     if (state == GridLayer.STATE_MEDIA_SETS || state == GridLayer.STATE_TIMELINE) {
41                         position.y = -0.1f;
42                     }
43                     float width = camera.mItemWidth;
44                     float height = camera.mItemHeight;
45                     if (portrait != 0) {
46                         float temp = width;
47                         width = height;
48                         height = temp;
49                     }
50                     camera.moveTo(position.x, position.y, zoomin ? camera.getDistanceToFitRect(width * oneByZoom, height * oneByZoom) : 0);
51                 } finally {
52                     pool.delete(position);
53                     pool.delete(deltaAnchorPosition);        
54                 }
55             } else {
56                 camera.moveYTo(0);
57                 camera.moveZTo(0);
58             }
59         }
60     }
61
62     // CR: line too long. Documentation--what are the semantics of the return value?
63     /**
64      */
65     public boolean constrainCameraForSlot(LayoutInterface layout, int slotIndex, Vector3f deltaAnchorPositionIn,
66             float currentFocusItemWidth, float currentFocusItemHeight) {
67         final GridCamera camera = mCamera;
68         final Pool<Vector3f> pool = sPool;
69         boolean retVal = false;
70         synchronized (camera) {
71             final Vector3f position = pool.create();
72             final Vector3f deltaAnchorPosition = pool.create();
73             final Vector3f topLeft = pool.create();
74             final Vector3f bottomRight = pool.create();
75             final Vector3f imgTopLeft = pool.create();
76             final Vector3f imgBottomRight = pool.create();
77
78             try {
79                 if (slotIndex >= 0) {
80                     deltaAnchorPosition.set(deltaAnchorPositionIn);
81                     GridCameraManager.getSlotPositionForSlotIndex(slotIndex, camera, layout, deltaAnchorPosition, position);
82                     position.x *= camera.mOneByScale;
83                     position.y = 0.0f;
84                     float width = (currentFocusItemWidth / 2);
85                     float height = (currentFocusItemHeight / 2);
86                     imgTopLeft.set(position.x - width, position.y - height, 0);
87                     imgBottomRight.set(position.x + width, position.y + height, 0);
88                     camera.convertToCameraSpace(0, 0, 0, topLeft);
89                     camera.convertToCameraSpace(camera.mWidth, camera.mHeight, 0, bottomRight);
90                     float leftExtent = topLeft.x - imgTopLeft.x;
91                     float rightExtent = bottomRight.x - imgBottomRight.x;
92                     camera.mConvergenceSpeed = 2.0f;
93
94                     if (leftExtent < 0) {
95                         retVal = true;
96                         camera.moveBy(-leftExtent, 0, 0);
97                     }
98                     if (rightExtent > 0) {
99                         retVal = true;
100                         camera.moveBy(-rightExtent, 0, 0);
101                     }
102                     float topExtent = topLeft.y - imgTopLeft.y;
103                     float bottomExtent = bottomRight.y - imgBottomRight.y;
104                     if (topExtent < 0) {
105                         camera.moveBy(0, -topExtent, 0);
106                     }
107                     if (bottomExtent > 0) {
108                         camera.moveBy(0, -bottomExtent, 0);
109                     }
110                 } 
111             } finally {
112                 pool.delete(position);
113                 pool.delete(deltaAnchorPosition);
114                 pool.delete(topLeft);
115                 pool.delete(bottomRight);
116                 pool.delete(imgTopLeft);
117                 pool.delete(imgBottomRight);
118             }
119         }
120         return retVal;
121     }
122
123     public void computeVisibleRange(MediaFeed feed, LayoutInterface layout, Vector3f deltaAnchorPositionIn,
124             IndexRange outVisibleRange, IndexRange outBufferedVisibleRange, IndexRange outCompleteRange, int state) {
125         GridCamera camera = mCamera;
126         Pool<Vector3f> pool = sPool;
127         float offset = (camera.mLookAtX * camera.mScale);
128         int itemWidth = camera.mItemWidth;
129         float maxIncrement = camera.mWidth * 0.5f + itemWidth;
130         float left = -maxIncrement + offset;
131         float right = left + 2.0f * maxIncrement;
132         if (state == GridLayer.STATE_MEDIA_SETS || state == GridLayer.STATE_TIMELINE) {
133             right += (itemWidth * 0.5f);
134         }
135         float top = -maxIncrement;
136         float bottom = camera.mHeight + maxIncrement;
137         // the hint to compute the visible display items
138         int numSlots = 0;
139         if (feed != null) {
140             numSlots = feed.getNumSlots();
141         }
142         synchronized (outCompleteRange) {
143             outCompleteRange.set(0, numSlots - 1);
144         }
145
146         Vector3f position = pool.create();
147         Vector3f deltaAnchorPosition = pool.create();
148         try {
149             int firstVisibleSlotIndex = 0;
150             int lastVisibleSlotIndex = numSlots - 1;
151             int leftEdge = firstVisibleSlotIndex;
152             int rightEdge = lastVisibleSlotIndex;
153             int index = (leftEdge + rightEdge) / 2;
154             lastVisibleSlotIndex = firstVisibleSlotIndex;
155             deltaAnchorPosition.set(deltaAnchorPositionIn);
156             while (index != leftEdge) {
157                 GridCameraManager.getSlotPositionForSlotIndex(index, camera, layout, deltaAnchorPosition, position);
158                 if (FloatUtils.boundsContainsPoint(left, right, top, bottom, position.x, position.y)) {
159                     // this index is visible
160                     firstVisibleSlotIndex = index;
161                     lastVisibleSlotIndex = index;
162                     break;
163                 } else {
164                     if (position.x > left) {
165                         rightEdge = index;
166                     } else {
167                         leftEdge = index;
168                     }
169                     index = (leftEdge + rightEdge) / 2;
170                 }
171             }
172             // CR: comments would make me a happy panda.
173             while (firstVisibleSlotIndex >= 0 && firstVisibleSlotIndex < numSlots) {
174                 GridCameraManager.getSlotPositionForSlotIndex(firstVisibleSlotIndex, camera, layout, deltaAnchorPosition, position);
175                 // CR: !fubar instead of fubar == false.
176                 if (FloatUtils.boundsContainsPoint(left, right, top, bottom, position.x, position.y) == false) {
177                     ++firstVisibleSlotIndex;
178                     break;
179                 } else {
180                     --firstVisibleSlotIndex;
181                 }
182             }
183             while (lastVisibleSlotIndex >= 0 && lastVisibleSlotIndex < numSlots) {
184                 GridCameraManager.getSlotPositionForSlotIndex(lastVisibleSlotIndex, camera, layout, deltaAnchorPosition, position);
185                 if (FloatUtils.boundsContainsPoint(left, right, top, bottom, position.x, position.y) == false) {
186                     --lastVisibleSlotIndex;
187                     break;
188                 } else {
189                     ++lastVisibleSlotIndex;
190                 }
191             }
192             if (firstVisibleSlotIndex < 0)
193                 firstVisibleSlotIndex = 0;
194             if (lastVisibleSlotIndex >= numSlots)
195                 lastVisibleSlotIndex = numSlots - 1;
196             synchronized (outVisibleRange) {
197                 outVisibleRange.set(firstVisibleSlotIndex, lastVisibleSlotIndex);
198             }
199             if (feed != null) {
200                 feed.setVisibleRange(firstVisibleSlotIndex, lastVisibleSlotIndex);
201             }
202             final int buffer = 24;
203             firstVisibleSlotIndex = ((firstVisibleSlotIndex - buffer) / buffer) * buffer;
204             lastVisibleSlotIndex += buffer;
205             lastVisibleSlotIndex = (lastVisibleSlotIndex / buffer) * buffer;
206             if (firstVisibleSlotIndex < 0) {
207                 firstVisibleSlotIndex = 0;
208             }
209             if (lastVisibleSlotIndex >= numSlots) {
210                 lastVisibleSlotIndex = numSlots - 1;
211             }
212             synchronized (outBufferedVisibleRange) {
213                 outBufferedVisibleRange.set(firstVisibleSlotIndex, lastVisibleSlotIndex);
214             }
215         } finally {
216             pool.delete(position);
217             pool.delete(deltaAnchorPosition);
218         }
219     }
220
221     public static final void getSlotPositionForSlotIndex(int slotIndex, GridCamera camera, LayoutInterface layout,
222             Vector3f deltaAnchorPosition, Vector3f outVal) {
223         layout.getPositionForSlotIndex(slotIndex, camera.mItemWidth, camera.mItemHeight, outVal);
224         outVal.subtract(deltaAnchorPosition);
225     }
226
227     public static final float getFillScreenZoomValue(GridCamera camera, Pool<Vector3f> pool, float currentFocusItemWidth,
228             float currentFocusItemHeight) {
229         final Vector3f topLeft = pool.create();
230         final Vector3f bottomRight = pool.create();
231         float potentialZoomValue = 1.0f;
232         try {
233             camera.convertToCameraSpace(0, 0, 0, topLeft);
234             camera.convertToCameraSpace(camera.mWidth, camera.mHeight, 0, bottomRight);
235             float xExtent = Math.abs(topLeft.x - bottomRight.x) / currentFocusItemWidth;
236             float yExtent = Math.abs(topLeft.y - bottomRight.y) / currentFocusItemHeight;
237             potentialZoomValue = Math.max(xExtent, yExtent);
238         } finally {
239             pool.delete(topLeft);
240             pool.delete(bottomRight);
241         }
242         return potentialZoomValue;
243     }
244 }