1 /* 2 * Copyright 2021 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 package org.skia.androidkit; 9 10 import android.util.Log; 11 12 /* 13 * 4x4 matrix backed by SkM44 14 */ 15 public class Matrix { 16 private long mNativeInstance; 17 18 /* 19 * Returns identity Matrix 20 */ Matrix()21 public Matrix() { 22 mNativeInstance = nCreate(1, 0, 0, 0, 23 0, 1, 0, 0, 24 0, 0, 1, 0, 25 0, 0, 0, 1); 26 } 27 28 /* 29 * Returns Matrix populated with values passed in (row-major order). 30 */ Matrix(float m0, float m4, float m8, float m12, float m1, float m5, float m9, float m13, float m2, float m6, float m10, float m14, float m3, float m7, float m11, float m15)31 public Matrix(float m0, float m4, float m8, float m12, 32 float m1, float m5, float m9, float m13, 33 float m2, float m6, float m10, float m14, 34 float m3, float m7, float m11, float m15) { 35 mNativeInstance = nCreate(m0, m4, m8, m12, 36 m1, m5, m9, m13, 37 m2, m6, m10, m14, 38 m3, m7, m11, m15); 39 } 40 Matrix(long nativeInstance)41 Matrix(long nativeInstance) { 42 mNativeInstance = nativeInstance; 43 } 44 makeLookAt(float eyeX, float eyeY, float eyeZ, float coaX, float coaY, float coaZ, float upX, float upY, float upZ)45 public static Matrix makeLookAt(float eyeX, float eyeY, float eyeZ, 46 float coaX, float coaY, float coaZ, 47 float upX, float upY, float upZ) { 48 return new Matrix(nCreateLookAt(eyeX, eyeY, eyeZ, 49 coaX, coaY, coaZ, 50 upX, upY, upZ)); 51 } 52 makePerspective(float near, float far, float angle)53 public static Matrix makePerspective(float near, float far, float angle) { 54 return new Matrix(nCreatePerspective(near, far, angle)); 55 } 56 makeInverse(Matrix m)57 public static Matrix makeInverse(Matrix m) throws RuntimeException { 58 long nativeMatrix = nInverse(m.getNativeInstance()); 59 if (nativeMatrix == 0){ 60 // extend generic exception? 61 throw new RuntimeException("Matrix m was not an invertible Matrix"); 62 } 63 return new Matrix(nativeMatrix); 64 } 65 makeTranspose(Matrix m)66 public static Matrix makeTranspose(Matrix m) { 67 long nativeTranspose = nTranspose(m.getNativeInstance()); 68 return new Matrix(nativeTranspose); 69 } 70 71 /* 72 * A: this Matrix 73 * B: Matrix passed in 74 * Concat A * B, return new Matrix C as result 75 */ makeConcat(Matrix a, Matrix b)76 public static Matrix makeConcat(Matrix a, Matrix b) { 77 long nativeA = a.mNativeInstance; 78 long nativeB = b.mNativeInstance; 79 long nativeC = nConcat(nativeA, nativeB); 80 return new Matrix(nativeC); 81 } 82 83 /* 84 * Convenience method 85 * Calls getRowMajorArray and indexes to the appropriate position 86 */ getAtRowCol(int r, int c)87 public float getAtRowCol(int r, int c) { 88 float[] a = this.getRowMajor(); 89 return a[r*4 + c]; 90 } 91 getRowMajor()92 public float[] getRowMajor() { 93 float[] vals = nGetRowMajor(this.mNativeInstance); 94 if (vals == null) { 95 throw new RuntimeException("Cannot make native float array, out of memory"); 96 } 97 return nGetRowMajor(this.mNativeInstance); 98 } 99 100 /* 101 * A: this Matrix 102 * B: Matrix passed in 103 * Concat B * A, store result in Matrix A 104 */ preConcat(Matrix b)105 public Matrix preConcat(Matrix b) { 106 long nativeA = this.mNativeInstance; 107 long nativeB = b.mNativeInstance; 108 nPreConcat(nativeA, nativeB); 109 return this; 110 } 111 112 /* 113 * Translates this Matrix by x, y, z 114 * Store result in caller Matrix 115 * returns reference to this Matrix for operation chaining 116 */ translate(float x, float y, float z)117 public Matrix translate(float x, float y, float z) { 118 nTranslate(this.mNativeInstance, x, y, z); 119 return this; 120 } translate(float x, float y)121 public Matrix translate(float x, float y) { 122 return translate(x, y, 0); 123 } 124 125 /* 126 * Scales this Matrix by x, y, z 127 * Store result in caller Matrix 128 * returns reference to this Matrix for operation chaining 129 */ scale(float x, float y, float z)130 public Matrix scale(float x, float y, float z) { 131 nScale(this.mNativeInstance, x, y, z); 132 return this; 133 } scale(float x, float y)134 public Matrix scale(float x, float y) { 135 return scale(x, y, 1); 136 } 137 138 /* 139 * Rotates this Matrix along the x-axis by rad radians 140 * Store result in caller Matrix 141 * returns reference to this Matrix for operation chaining 142 */ rotateX(float rad)143 public Matrix rotateX(float rad) { 144 nRotate(this.mNativeInstance, 1, 0, 0, rad); 145 return this; 146 } 147 148 /* 149 * Rotates this Matrix along the y-axis by rad radians 150 * Store result in caller Matrix 151 * returns reference to this Matrix for operation chaining 152 */ rotateY(float rad)153 public Matrix rotateY(float rad) { 154 nRotate(this.mNativeInstance, 0, 1, 0, rad); 155 return this; 156 } 157 158 /* 159 * Rotates this Matrix along the z-axis by rad radians 160 * Store result in caller Matrix 161 * returns reference to this Matrix for operation chaining 162 */ rotateZ(float rad)163 public Matrix rotateZ(float rad) { 164 nRotate(this.mNativeInstance, 0, 0, 1, rad); 165 return this; 166 } 167 168 /* 169 * Rotates this Matrix along the (x,y,z) axis by rad radians 170 * Store result in caller Matrix 171 * returns reference to this Matrix for operation chaining 172 */ rotate(float x, float y, float z, float rad)173 public Matrix rotate(float x, float y, float z, float rad) { 174 nRotate(this.mNativeInstance, x, y, z, rad); 175 return this; 176 } 177 178 /** 179 * Releases any resources associated with this Matrix. 180 */ release()181 public void release() { 182 nRelease(mNativeInstance); 183 mNativeInstance = 0; 184 } 185 186 @Override finalize()187 protected void finalize() throws Throwable { 188 release(); 189 } 190 191 // package private getNativeInstance()192 long getNativeInstance() { return mNativeInstance; } 193 nCreate(float m0, float m4, float m8, float m12, float m1, float m5, float m9, float m13, float m2, float m6, float m10, float m14, float m3, float m7, float m11, float m15)194 private static native long nCreate(float m0, float m4, float m8, float m12, 195 float m1, float m5, float m9, float m13, 196 float m2, float m6, float m10, float m14, 197 float m3, float m7, float m11, float m15); nCreateLookAt(float eyeX, float eyeY, float eyeZ, float coaX, float coaY, float coaZ, float upX, float upY, float upZ)198 private static native long nCreateLookAt(float eyeX, float eyeY, float eyeZ, 199 float coaX, float coaY, float coaZ, 200 float upX, float upY, float upZ); nCreatePerspective(float near, float far, float angle)201 private static native long nCreatePerspective(float near, float far, float angle); nRelease(long nativeInstance)202 private static native void nRelease(long nativeInstance); nGetRowMajor(long mNativeInstance)203 private static native float[] nGetRowMajor(long mNativeInstance); nInverse(long mNativeInstance)204 private static native long nInverse(long mNativeInstance); nTranspose(long mNativeInstance)205 private static native long nTranspose(long mNativeInstance); nPreConcat(long mNativeInstanceA, long mNativeInstanceB)206 private static native void nPreConcat(long mNativeInstanceA, long mNativeInstanceB); nConcat(long mNativeInstanceA, long mNativeInstanceB)207 private static native long nConcat(long mNativeInstanceA, long mNativeInstanceB); nTranslate(long mNativeInstance, float x, float y, float z)208 private static native void nTranslate(long mNativeInstance, float x, float y, float z); nScale(long mNativeInstance, float x, float y, float z)209 private static native void nScale(long mNativeInstance, float x, float y, float z); nRotate(long mNativeInstance, float x, float y, float z, float rad)210 private static native void nRotate(long mNativeInstance, float x, float y, float z, float rad); 211 } 212