3d view system!
True 3d transformations are now supported by DisplayLists and the
renderer, initially with the translationZ property on view.
Renderer operations used directly by DisplayList (formerly,
clip/save/restore/saveLayer) are now more simply managed by allocating
them temporarily on the handler's allocator, which exists for a single
frame. This is much simpler than continuing to expand the pool of
pre-allocated DisplayListOps now that more operations are called
directly by DisplayList, especially with z ordered drawing.
Still TODO:
-APIs for camera positioning, shadows
-Make Z apis public, and expose through XML
-Make invalidation / input 3d aware
Change-Id: I95fe6fa03f9b6ddd34a7e0c6ec8dd9fe47c6c6eb
diff --git a/libs/hwui/Matrix.cpp b/libs/hwui/Matrix.cpp
index ba22071..4f5cd26 100644
--- a/libs/hwui/Matrix.cpp
+++ b/libs/hwui/Matrix.cpp
@@ -89,8 +89,9 @@
float m01 = data[kSkewX];
float m10 = data[kSkewY];
float m11 = data[kScaleY];
+ float m32 = data[kTranslateZ];
- if (m01 != 0.0f || m10 != 0.0f) {
+ if (m01 != 0.0f || m10 != 0.0f || m32 != 0.0f) {
mType |= kTypeAffine;
}
@@ -131,11 +132,13 @@
}
bool Matrix4::isPureTranslate() const {
- return getGeometryType() <= kTypeTranslate;
+ // NOTE: temporary hack to workaround ignoreTransform behavior with Z values
+ // TODO: separate this into isPure2dTranslate vs isPure3dTranslate
+ return getGeometryType() <= kTypeTranslate && (data[kTranslateZ] == 0.0f);
}
bool Matrix4::isSimple() const {
- return getGeometryType() <= (kTypeScale | kTypeTranslate);
+ return getGeometryType() <= (kTypeScale | kTypeTranslate) && (data[kTranslateZ] == 0.0f);
}
bool Matrix4::isIdentity() const {
@@ -369,6 +372,84 @@
mType = kTypeUnknown;
}
+// translated from android.opengl.Matrix#frustumM()
+void Matrix4::loadFrustum(float left, float top, float right, float bottom, float near, float far) {
+ float r_width = 1.0f / (right - left);
+ float r_height = 1.0f / (top - bottom);
+ float r_depth = 1.0f / (near - far);
+ float x = 2.0f * (near * r_width);
+ float y = 2.0f * (near * r_height);
+ float A = (right + left) * r_width;
+ float B = (top + bottom) * r_height;
+ float C = (far + near) * r_depth;
+ float D = 2.0f * (far * near * r_depth);
+
+ memset(&data, 0, sizeof(data));
+ mType = kTypeUnknown;
+
+ data[kScaleX] = x;
+ data[kScaleY] = y;
+ data[8] = A;
+ data[9] = B;
+ data[kScaleZ] = C;
+ data[kTranslateZ] = D;
+ data[11] = -1.0f;
+}
+
+// translated from android.opengl.Matrix#setLookAtM()
+void Matrix4::loadLookAt(float eyeX, float eyeY, float eyeZ,
+ float centerX, float centerY, float centerZ,
+ float upX, float upY, float upZ) {
+ float fx = centerX - eyeX;
+ float fy = centerY - eyeY;
+ float fz = centerZ - eyeZ;
+
+ // Normalize f
+ float rlf = 1.0f / sqrt(fx*fx + fy*fy + fz*fz);
+ fx *= rlf;
+ fy *= rlf;
+ fz *= rlf;
+
+ // compute s = f x up (x means "cross product")
+ float sx = fy * upZ - fz * upY;
+ float sy = fz * upX - fx * upZ;
+ float sz = fx * upY - fy * upX;
+
+ // and normalize s
+ float rls = 1.0f / sqrt(sx*sx + sy*sy + sz*sz);
+ sx *= rls;
+ sy *= rls;
+ sz *= rls;
+
+ // compute u = s x f
+ float ux = sy * fz - sz * fy;
+ float uy = sz * fx - sx * fz;
+ float uz = sx * fy - sy * fx;
+
+ mType = kTypeUnknown;
+ data[0] = sx;
+ data[1] = ux;
+ data[2] = -fx;
+ data[3] = 0.0f;
+
+ data[4] = sy;
+ data[5] = uy;
+ data[6] = -fy;
+ data[7] = 0.0f;
+
+ data[8] = sz;
+ data[9] = uz;
+ data[10] = -fz;
+ data[11] = 0.0f;
+
+ data[12] = 0.0f;
+ data[13] = 0.0f;
+ data[14] = 0.0f;
+ data[15] = 1.0f;
+
+ translate(-eyeX, -eyeY, -eyeZ);
+}
+
void Matrix4::loadOrtho(float left, float right, float bottom, float top, float near, float far) {
loadIdentity();
@@ -382,6 +463,14 @@
mType = kTypeTranslate | kTypeScale | kTypeRectToRect;
}
+void Matrix4::mapPoint3d(Vector3& vec) const {
+ //TODO: optimize simple case
+ Vector3 orig(vec);
+ vec.x = orig.x * data[kScaleX] + orig.y * data[kSkewX] + orig.z * data[8] + data[kTranslateX];
+ vec.y = orig.x * data[kSkewY] + orig.y * data[kScaleY] + orig.z * data[9] + data[kTranslateY];
+ vec.z = orig.x * data[2] + orig.y * data[6] + orig.z * data[kScaleZ] + data[kTranslateZ];
+}
+
#define MUL_ADD_STORE(a, b, c) a = (a) * (b) + (c)
void Matrix4::mapPoint(float& x, float& y) const {