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