Matrix.h revision f57776b2d195f0937906eb88b777bb55ccc36967
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef ANDROID_HWUI_MATRIX_H 18#define ANDROID_HWUI_MATRIX_H 19 20#include <SkMatrix.h> 21 22#include <cutils/compiler.h> 23 24#include "Rect.h" 25 26namespace android { 27namespace uirenderer { 28 29#define MATRIX_STRING "[%.2f %.2f %.2f] [%.2f %.2f %.2f] [%.2f %.2f %.2f]" 30#define MATRIX_ARGS(m) \ 31 (m)->get(0), (m)->get(1), (m)->get(2), \ 32 (m)->get(3), (m)->get(4), (m)->get(5), \ 33 (m)->get(6), (m)->get(7), (m)->get(8) 34 35/////////////////////////////////////////////////////////////////////////////// 36// Classes 37/////////////////////////////////////////////////////////////////////////////// 38 39class ANDROID_API Matrix4 { 40public: 41 float data[16]; 42 43 enum Entry { 44 kScaleX = 0, 45 kSkewY = 1, 46 kPerspective0 = 3, 47 kSkewX = 4, 48 kScaleY = 5, 49 kPerspective1 = 7, 50 kScaleZ = 10, 51 kTranslateX = 12, 52 kTranslateY = 13, 53 kTranslateZ = 14, 54 kPerspective2 = 15 55 }; 56 57 // NOTE: The flags from kTypeIdentity to kTypePerspective 58 // must be kept in sync with the type flags found 59 // in SkMatrix 60 enum Type { 61 kTypeIdentity = 0, 62 kTypeTranslate = 0x1, 63 kTypeScale = 0x2, 64 kTypeAffine = 0x4, 65 kTypePerspective = 0x8, 66 kTypeRectToRect = 0x10, 67 kTypeUnknown = 0x20, 68 }; 69 70 static const int sGeometryMask = 0xf; 71 72 Matrix4() { 73 loadIdentity(); 74 } 75 76 Matrix4(const float* v) { 77 load(v); 78 } 79 80 Matrix4(const Matrix4& v) { 81 load(v); 82 } 83 84 Matrix4(const SkMatrix& v) { 85 load(v); 86 } 87 88 float operator[](int index) const { 89 return data[index]; 90 } 91 92 float& operator[](int index) { 93 mType = kTypeUnknown; 94 return data[index]; 95 } 96 97 Matrix4& operator=(const SkMatrix& v) { 98 load(v); 99 return *this; 100 } 101 102 friend bool operator==(const Matrix4& a, const Matrix4& b) { 103 return !memcmp(&a.data[0], &b.data[0], 16 * sizeof(float)); 104 } 105 106 friend bool operator!=(const Matrix4& a, const Matrix4& b) { 107 return !(a == b); 108 } 109 110 void loadIdentity(); 111 112 void load(const float* v); 113 void load(const Matrix4& v); 114 void load(const SkMatrix& v); 115 116 void loadInverse(const Matrix4& v); 117 118 void loadTranslate(float x, float y, float z); 119 void loadScale(float sx, float sy, float sz); 120 void loadSkew(float sx, float sy); 121 void loadRotate(float angle); 122 void loadRotate(float angle, float x, float y, float z); 123 void loadMultiply(const Matrix4& u, const Matrix4& v); 124 void loadFrustum(float left, float top, float right, float bottom, float near, float far); 125 void loadLookAt(float eyeX, float eyeY, float eyeZ, 126 float centerX, float centerY, float centerZ, 127 float upX, float upY, float upZ); 128 129 void loadOrtho(float left, float right, float bottom, float top, float near, float far); 130 131 uint8_t getType() const; 132 133 void multiply(const Matrix4& v) { 134 Matrix4 u; 135 u.loadMultiply(*this, v); 136 load(u); 137 } 138 139 void multiply(float v); 140 141 void translate(float x, float y, float z = 0) { 142 if ((getType() & sGeometryMask) <= kTypeTranslate) { 143 data[kTranslateX] += x; 144 data[kTranslateY] += y; 145 data[kTranslateZ] += z; 146 } else { 147 // Doing a translation will only affect the translate bit of the type 148 // Save the type 149 uint8_t type = mType; 150 151 Matrix4 u; 152 u.loadTranslate(x, y, z); 153 multiply(u); 154 155 // Restore the type and fix the translate bit 156 mType = type; 157 if (data[kTranslateX] != 0.0f || data[kTranslateY] != 0.0f) { 158 mType |= kTypeTranslate; 159 } else { 160 mType &= ~kTypeTranslate; 161 } 162 } 163 } 164 165 void scale(float sx, float sy, float sz) { 166 Matrix4 u; 167 u.loadScale(sx, sy, sz); 168 multiply(u); 169 } 170 171 void skew(float sx, float sy) { 172 Matrix4 u; 173 u.loadSkew(sx, sy); 174 multiply(u); 175 } 176 177 void rotate(float angle, float x, float y, float z) { 178 Matrix4 u; 179 u.loadRotate(angle, x, y, z); 180 multiply(u); 181 } 182 183 /** 184 * If the matrix is identity or translate and/or scale. 185 */ 186 bool isSimple() const; 187 bool isPureTranslate() const; 188 bool isIdentity() const; 189 bool isPerspective() const; 190 bool rectToRect() const; 191 bool positiveScale() const; 192 193 bool changesBounds() const; 194 195 void copyTo(float* v) const; 196 void copyTo(SkMatrix& v) const; 197 198 void mapPoint3d(Vector3& vec) const; 199 void mapPoint(float& x, float& y) const; // 2d only 200 void mapRect(Rect& r) const; // 2d only 201 202 float getTranslateX() const; 203 float getTranslateY() const; 204 205 void decomposeScale(float& sx, float& sy) const; 206 207 void dump() const; 208 209 static const Matrix4& identity(); 210 211private: 212 mutable uint8_t mType; 213 214 inline float get(int i, int j) const { 215 return data[i * 4 + j]; 216 } 217 218 inline void set(int i, int j, float v) { 219 data[i * 4 + j] = v; 220 } 221 222 uint8_t getGeometryType() const; 223 224}; // class Matrix4 225 226/////////////////////////////////////////////////////////////////////////////// 227// Types 228/////////////////////////////////////////////////////////////////////////////// 229 230typedef Matrix4 mat4; 231 232}; // namespace uirenderer 233}; // namespace android 234 235#endif // ANDROID_HWUI_MATRIX_H 236