return 1;
}
+#elsif 1
+// Adapted from code contributed to Mesa by David Moore (Mesa 7.6 under SGI Free License B - which is MIT/X11-type)
+// number of multiplications reduced by divVerent, yet to be benchmarked
+int Matrix4x4_Invert_Full (matrix4x4_t *out, const matrix4x4_t *in1)
+{
+ matrix4x4_t temp;
+ double det;
+ int i, j;
+
+#ifdef MATRIX4x4_OPENGLORIENTATION
+ temp.m[0][0] = in1->m[1][1]*(in1->m[2][2]*in1->m[3][3] - in1->m[2][3]*in1->m[3][2]) - in1->m[2][1]*(in1->m[1][2]*in1->m[3][3] - in1->m[1][3]*in1->m[3][2]) + in1->m[3][1]*(in1->m[1][2]*in1->m[2][3] - in1->m[1][3]*in1->m[2][2]);
+ temp.m[1][0] = -in1->m[1][0]*(in1->m[2][2]*in1->m[3][3] - in1->m[2][3]*in1->m[3][2]) + in1->m[2][0]*(in1->m[1][2]*in1->m[3][3] - in1->m[1][3]*in1->m[3][2]) - in1->m[3][0]*(in1->m[1][2]*in1->m[2][3] - in1->m[1][3]*in1->m[2][2]);
+ temp.m[2][0] = in1->m[1][0]*(in1->m[2][1]*in1->m[3][3] - in1->m[2][3]*in1->m[3][1]) - in1->m[2][0]*(in1->m[1][1]*in1->m[3][3] - in1->m[1][3]*in1->m[3][1]) + in1->m[3][0]*(in1->m[1][1]*in1->m[2][3] - in1->m[1][3]*in1->m[2][1]);
+ temp.m[3][0] = -in1->m[1][0]*(in1->m[2][1]*in1->m[3][2] - in1->m[2][2]*in1->m[3][1]) + in1->m[2][0]*(in1->m[1][1]*in1->m[3][2] - in1->m[1][2]*in1->m[3][1]) - in1->m[3][0]*(in1->m[1][1]*in1->m[2][2] - in1->m[1][2]*in1->m[2][1]);
+ temp.m[0][1] = -in1->m[0][1]*(in1->m[2][2]*in1->m[3][3] - in1->m[2][3]*in1->m[3][2]) + in1->m[2][1]*(in1->m[0][2]*in1->m[3][3] - in1->m[0][3]*in1->m[3][2]) - in1->m[3][1]*(in1->m[0][2]*in1->m[2][3] - in1->m[0][3]*in1->m[2][2]);
+ temp.m[1][1] = in1->m[0][0]*(in1->m[2][2]*in1->m[3][3] - in1->m[2][3]*in1->m[3][2]) - in1->m[2][0]*(in1->m[0][2]*in1->m[3][3] - in1->m[0][3]*in1->m[3][2]) + in1->m[3][0]*(in1->m[0][2]*in1->m[2][3] - in1->m[0][3]*in1->m[2][2]);
+ temp.m[2][1] = -in1->m[0][0]*(in1->m[2][1]*in1->m[3][3] - in1->m[2][3]*in1->m[3][1]) + in1->m[2][0]*(in1->m[0][1]*in1->m[3][3] - in1->m[0][3]*in1->m[3][1]) - in1->m[3][0]*(in1->m[0][1]*in1->m[2][3] - in1->m[0][3]*in1->m[2][1]);
+ temp.m[3][1] = in1->m[0][0]*(in1->m[2][1]*in1->m[3][2] - in1->m[2][2]*in1->m[3][1]) - in1->m[2][0]*(in1->m[0][1]*in1->m[3][2] - in1->m[0][2]*in1->m[3][1]) + in1->m[3][0]*(in1->m[0][1]*in1->m[2][2] - in1->m[0][2]*in1->m[2][1]);
+ temp.m[0][2] = in1->m[0][1]*(in1->m[1][2]*in1->m[3][3] - in1->m[1][3]*in1->m[3][2]) - in1->m[1][1]*(in1->m[0][2]*in1->m[3][3] - in1->m[0][3]*in1->m[3][2]) + in1->m[3][1]*(in1->m[0][2]*in1->m[1][3] - in1->m[0][3]*in1->m[1][2]);
+ temp.m[1][2] = -in1->m[0][0]*(in1->m[1][2]*in1->m[3][3] - in1->m[1][3]*in1->m[3][2]) + in1->m[1][0]*(in1->m[0][2]*in1->m[3][3] - in1->m[0][3]*in1->m[3][2]) - in1->m[3][0]*(in1->m[0][2]*in1->m[1][3] - in1->m[0][3]*in1->m[1][2]);
+ temp.m[2][2] = in1->m[0][0]*(in1->m[1][1]*in1->m[3][3] - in1->m[1][3]*in1->m[3][1]) - in1->m[1][0]*(in1->m[0][1]*in1->m[3][3] - in1->m[0][3]*in1->m[3][1]) + in1->m[3][0]*(in1->m[0][1]*in1->m[1][3] - in1->m[0][3]*in1->m[1][1]);
+ temp.m[3][2] = -in1->m[0][0]*(in1->m[1][1]*in1->m[3][2] - in1->m[1][2]*in1->m[3][1]) + in1->m[1][0]*(in1->m[0][1]*in1->m[3][2] - in1->m[0][2]*in1->m[3][1]) - in1->m[3][0]*(in1->m[0][1]*in1->m[1][2] - in1->m[0][2]*in1->m[1][1]);
+ temp.m[0][3] = -in1->m[0][1]*(in1->m[1][2]*in1->m[2][3] - in1->m[1][3]*in1->m[2][2]) + in1->m[1][1]*(in1->m[0][2]*in1->m[2][3] - in1->m[0][3]*in1->m[2][2]) - in1->m[2][1]*(in1->m[0][2]*in1->m[1][3] - in1->m[0][3]*in1->m[1][2]);
+ temp.m[1][3] = in1->m[0][0]*(in1->m[1][2]*in1->m[2][3] - in1->m[1][3]*in1->m[2][2]) - in1->m[1][0]*(in1->m[0][2]*in1->m[2][3] - in1->m[0][3]*in1->m[2][2]) + in1->m[2][0]*(in1->m[0][2]*in1->m[1][3] - in1->m[0][3]*in1->m[1][2]);
+ temp.m[2][3] = -in1->m[0][0]*(in1->m[1][1]*in1->m[2][3] - in1->m[1][3]*in1->m[2][1]) + in1->m[1][0]*(in1->m[0][1]*in1->m[2][3] - in1->m[0][3]*in1->m[2][1]) - in1->m[2][0]*(in1->m[0][1]*in1->m[1][3] - in1->m[0][3]*in1->m[1][1]);
+ temp.m[3][3] = in1->m[0][0]*(in1->m[1][1]*in1->m[2][2] - in1->m[1][2]*in1->m[2][1]) - in1->m[1][0]*(in1->m[0][1]*in1->m[2][2] - in1->m[0][2]*in1->m[2][1]) + in1->m[2][0]*(in1->m[0][1]*in1->m[1][2] - in1->m[0][2]*in1->m[1][1]);
+#else
+ temp.m[0][0] = in1->m[1][1]*(in1->m[2][2]*in1->m[3][3] - in1->m[3][2]*in1->m[2][3]) - in1->m[1][2]*(in1->m[2][1]*in1->m[3][3] - in1->m[3][1]*in1->m[2][3]) + in1->m[1][3]*(in1->m[2][1]*in1->m[3][2] - in1->m[3][1]*in1->m[2][2]);
+ temp.m[0][1] = -in1->m[0][1]*(in1->m[2][2]*in1->m[3][3] - in1->m[3][2]*in1->m[2][3]) + in1->m[0][2]*(in1->m[2][1]*in1->m[3][3] - in1->m[3][1]*in1->m[2][3]) - in1->m[0][3]*(in1->m[2][1]*in1->m[3][2] + in1->m[3][1]*in1->m[2][2]);
+ temp.m[0][2] = in1->m[0][1]*(in1->m[1][2]*in1->m[3][3] - in1->m[3][2]*in1->m[1][3]) - in1->m[0][2]*(in1->m[1][1]*in1->m[3][3] - in1->m[3][1]*in1->m[1][3]) + in1->m[0][3]*(in1->m[1][1]*in1->m[3][2] - in1->m[3][1]*in1->m[1][2]);
+ temp.m[0][3] = -in1->m[0][1]*(in1->m[1][2]*in1->m[2][3] - in1->m[2][2]*in1->m[1][3]) + in1->m[0][2]*(in1->m[1][1]*in1->m[2][3] - in1->m[2][1]*in1->m[1][3]) - in1->m[0][3]*(in1->m[1][1]*in1->m[2][2] + in1->m[2][1]*in1->m[1][2]);
+ temp.m[1][0] = -in1->m[1][0]*(in1->m[2][2]*in1->m[3][3] - in1->m[3][2]*in1->m[2][3]) + in1->m[1][2]*(in1->m[2][0]*in1->m[3][3] - in1->m[3][0]*in1->m[2][3]) - in1->m[1][3]*(in1->m[2][0]*in1->m[3][2] + in1->m[3][0]*in1->m[2][2]);
+ temp.m[1][1] = in1->m[0][0]*(in1->m[2][2]*in1->m[3][3] - in1->m[3][2]*in1->m[2][3]) - in1->m[0][2]*(in1->m[2][0]*in1->m[3][3] - in1->m[3][0]*in1->m[2][3]) + in1->m[0][3]*(in1->m[2][0]*in1->m[3][2] - in1->m[3][0]*in1->m[2][2]);
+ temp.m[1][2] = -in1->m[0][0]*(in1->m[1][2]*in1->m[3][3] - in1->m[3][2]*in1->m[1][3]) + in1->m[0][2]*(in1->m[1][0]*in1->m[3][3] - in1->m[3][0]*in1->m[1][3]) - in1->m[0][3]*(in1->m[1][0]*in1->m[3][2] + in1->m[3][0]*in1->m[1][2]);
+ temp.m[1][3] = in1->m[0][0]*(in1->m[1][2]*in1->m[2][3] - in1->m[2][2]*in1->m[1][3]) - in1->m[0][2]*(in1->m[1][0]*in1->m[2][3] - in1->m[2][0]*in1->m[1][3]) + in1->m[0][3]*(in1->m[1][0]*in1->m[2][2] - in1->m[2][0]*in1->m[1][2]);
+ temp.m[2][0] = in1->m[1][0]*(in1->m[2][1]*in1->m[3][3] - in1->m[3][1]*in1->m[2][3]) - in1->m[1][1]*(in1->m[2][0]*in1->m[3][3] - in1->m[3][0]*in1->m[2][3]) + in1->m[1][3]*(in1->m[2][0]*in1->m[3][1] - in1->m[3][0]*in1->m[2][1]);
+ temp.m[2][1] = -in1->m[0][0]*(in1->m[2][1]*in1->m[3][3] - in1->m[3][1]*in1->m[2][3]) + in1->m[0][1]*(in1->m[2][0]*in1->m[3][3] - in1->m[3][0]*in1->m[2][3]) - in1->m[0][3]*(in1->m[2][0]*in1->m[3][1] + in1->m[3][0]*in1->m[2][1]);
+ temp.m[2][2] = in1->m[0][0]*(in1->m[1][1]*in1->m[3][3] - in1->m[3][1]*in1->m[1][3]) - in1->m[0][1]*(in1->m[1][0]*in1->m[3][3] - in1->m[3][0]*in1->m[1][3]) + in1->m[0][3]*(in1->m[1][0]*in1->m[3][1] - in1->m[3][0]*in1->m[1][1]);
+ temp.m[2][3] = -in1->m[0][0]*(in1->m[1][1]*in1->m[2][3] - in1->m[2][1]*in1->m[1][3]) + in1->m[0][1]*(in1->m[1][0]*in1->m[2][3] - in1->m[2][0]*in1->m[1][3]) - in1->m[0][3]*(in1->m[1][0]*in1->m[2][1] + in1->m[2][0]*in1->m[1][1]);
+ temp.m[3][0] = -in1->m[1][0]*(in1->m[2][1]*in1->m[3][2] - in1->m[3][1]*in1->m[2][2]) + in1->m[1][1]*(in1->m[2][0]*in1->m[3][2] - in1->m[3][0]*in1->m[2][2]) - in1->m[1][2]*(in1->m[2][0]*in1->m[3][1] + in1->m[3][0]*in1->m[2][1]);
+ temp.m[3][1] = in1->m[0][0]*(in1->m[2][1]*in1->m[3][2] - in1->m[3][1]*in1->m[2][2]) - in1->m[0][1]*(in1->m[2][0]*in1->m[3][2] - in1->m[3][0]*in1->m[2][2]) + in1->m[0][2]*(in1->m[2][0]*in1->m[3][1] - in1->m[3][0]*in1->m[2][1]);
+ temp.m[3][2] = -in1->m[0][0]*(in1->m[1][1]*in1->m[3][2] - in1->m[3][1]*in1->m[1][2]) + in1->m[0][1]*(in1->m[1][0]*in1->m[3][2] - in1->m[3][0]*in1->m[1][2]) - in1->m[0][2]*(in1->m[1][0]*in1->m[3][1] + in1->m[3][0]*in1->m[1][1]);
+ temp.m[3][3] = in1->m[0][0]*(in1->m[1][1]*in1->m[2][2] - in1->m[2][1]*in1->m[1][2]) - in1->m[0][1]*(in1->m[1][0]*in1->m[2][2] - in1->m[2][0]*in1->m[1][2]) + in1->m[0][2]*(in1->m[1][0]*in1->m[2][1] - in1->m[2][0]*in1->m[1][1]);
+#endif
+
+ det = in1->m[0][0]*temp.m[0][0] + in1->m[1][0]*temp.m[0][1] + in1->m[2][0]*temp.m[0][2] + in1->m[3][0]*temp.m[0][3];
+ if (det == 0.0f)
+ return 0;
+
+ det = 1.0f / det;
+
+ for (i = 0;i < 4;i++)
+ for (j = 0;j < 4;j++)
+ out->m[i][j] = temp.m[i][j] * det;
+
+ return 1;
+}
#else
int Matrix4x4_Invert_Full (matrix4x4_t *out, const matrix4x4_t *in1)
{