docs: public static void decomposeMetricCamera(DMatrixRMaj cameraMatrix, DMatrixRMaj K, Se3_F64 worldToView) {
  		DMatrixRMaj A = new DMatrixRMaj(3,3);
  		CommonOps_DDRM.extract(cameraMatrix, 0, 3, 0, 3, A, 0, 0);
  		worldToView.T.set(cameraMatrix.get(0,3),cameraMatrix.get(1,3),cameraMatrix.get(2,3));
  
  		QRDecomposition<DMatrixRMaj> qr = DecompositionFactory_DDRM.qr(3, 3);
  
  		// Need to do an RQ decomposition, but we only have QR
  		// by permuting the rows in KR we can get the desired result
  		DMatrixRMaj Pv = SpecializedOps_DDRM.pivotMatrix(null,new int[]{2,1,0},3,false);
  		DMatrixRMaj A_p = new DMatrixRMaj(3,3);
  		CommonOps_DDRM.mult(Pv,A,A_p);
  		CommonOps_DDRM.transpose(A_p);
  		if( !qr.decompose(A_p) )
  			throw new RuntimeException("QR decomposition failed!  Bad input?");
  
  		// extract the rotation
  		qr.getQ(A,false);
  		CommonOps_DDRM.multTransB(Pv,A,worldToView.R);
  
  		// extract the calibration matrix
  		qr.getR(K,false);
  		CommonOps_DDRM.multTransB(Pv,K,A);
  		CommonOps_DDRM.mult(A,Pv,K);
  
  		// there are four solutions, massage it so that it's the correct one.
  		// each of these row/column negations produces the same camera matrix
  		for (int i = 0; i < 3; i++) {
  			if( K.get(i,i) < 0) {
  				CommonOps_DDRM.scaleCol(-1,K,i);
  				CommonOps_DDRM.scaleRow(-1,worldToView.R,i);
  			}
  		}
  
  		// rotation matrices have det() == 1
  		if( CommonOps_DDRM.det(worldToView.R) < 0 ) {
  			CommonOps_DDRM.scale(-1,worldToView.R);
  			worldToView.T.scale(-1);
  		}
  
  		// make sure it's a proper camera matrix
  		CommonOps_DDRM.divide(K,K.get(2,2));
  
  		// could do a very fast triangule inverse. EJML doesn't have one for upper triangle, yet.
  		if( !CommonOps_DDRM.invert(K,A) )
  			throw new RuntimeException("Inverse failed!  Bad input?");
  
  		GeometryMath_F64.mult(A, worldToView.T, worldToView.T);
  	}