28package com.jogamp.math;
30import java.nio.FloatBuffer;
31import java.util.Locale;
33import com.jogamp.opengl.GLException;
35import jogamp.opengl.Debug;
37import com.jogamp.common.os.Platform;
84 public static final boolean DEBUG = Debug.debugExplicit(
"Math");
140 public static float[]
makeTranslation(
final float[] m,
final boolean initM,
final float tx,
final float ty,
final float tz) {
176 public static float[]
makeScale(
final float[] m,
final boolean initM,
final float sx,
final float sy,
final float sz) {
218 public static float[]
makeFrustum(
final float[] m,
final int m_offset,
final boolean initM,
219 final float left,
final float right,
220 final float bottom,
final float top,
221 final float zNear,
final float zFar)
throws GLException {
222 if( zNear <= 0.0f || zFar <= zNear ) {
223 throw new GLException(
"Requirements zNear > 0 and zFar > zNear, but zNear "+zNear+
", zFar "+zFar);
225 if( left == right || top == bottom) {
226 throw new GLException(
"GL_INVALID_VALUE: top,bottom and left,right must not be equal");
230 m[m_offset+1+4*0] = 0f;
231 m[m_offset+2+4*0] = 0f;
232 m[m_offset+3+4*0] = 0f;
234 m[m_offset+0+4*1] = 0f;
236 m[m_offset+2+4*1] = 0f;
237 m[m_offset+3+4*1] = 0f;
244 m[m_offset+0+4*3] = 0f;
245 m[m_offset+1+4*3] = 0f;
249 final float zNear2 = 2.0f*zNear;
250 final float dx=right-left;
251 final float dy=top-bottom;
252 final float dz=zFar-zNear;
253 final float A=(right+left)/dx;
254 final float B=(top+bottom)/dy;
255 final float C=-1.0f*(zFar+zNear)/dz;
256 final float D=-2.0f*(zFar*zNear)/dz;
258 m[m_offset+0+4*0] = zNear2/dx;
260 m[m_offset+1+4*1] = zNear2/dy;
262 m[m_offset+0+4*2] = A;
263 m[m_offset+1+4*2] = B;
264 m[m_offset+2+4*2] = C;
265 m[m_offset+3+4*2] = -1.0f;
267 m[m_offset+2+4*3] = D;
268 m[m_offset+3+4*3] = 0f;
292 public static float[]
makePerspective(
final float[] m,
final int m_off,
final boolean initM,
293 final float fovy_rad,
final float aspect,
final float zNear,
final float zFar)
throws GLException {
294 final float top =
tan(fovy_rad/2f) * zNear;
295 final float bottom = -1.0f * top;
296 final float left = aspect * bottom;
297 final float right = aspect * top;
298 return makeFrustum(m, m_off, initM, left, right, bottom, top, zNear, zFar);
329 public static float[]
makeLookAt(
final float[] m,
final int m_offset,
330 final float[] eye,
final int eye_offset,
331 final float[] center,
final int center_offset,
332 final float[] up,
final int up_offset,
333 final float[] mat4Tmp) {
334 final int forward_off = 0;
335 final int side_off = 3;
336 final int up2_off = 6;
339 mat4Tmp[0] = center[0+center_offset] - eye[0+eye_offset];
340 mat4Tmp[1] = center[1+center_offset] - eye[1+eye_offset];
341 mat4Tmp[2] = center[2+center_offset] - eye[2+eye_offset];
352 m[m_offset + 0 * 4 + 0] = mat4Tmp[0+side_off];
353 m[m_offset + 0 * 4 + 1] = mat4Tmp[0+up2_off];
354 m[m_offset + 0 * 4 + 2] = -mat4Tmp[0];
355 m[m_offset + 0 * 4 + 3] = 0;
357 m[m_offset + 1 * 4 + 0] = mat4Tmp[1+side_off];
358 m[m_offset + 1 * 4 + 1] = mat4Tmp[1+up2_off];
359 m[m_offset + 1 * 4 + 2] = -mat4Tmp[1];
360 m[m_offset + 1 * 4 + 3] = 0;
362 m[m_offset + 2 * 4 + 0] = mat4Tmp[2+side_off];
363 m[m_offset + 2 * 4 + 1] = mat4Tmp[2+up2_off];
364 m[m_offset + 2 * 4 + 2] = -mat4Tmp[2];
365 m[m_offset + 2 * 4 + 3] = 0;
367 m[m_offset + 3 * 4 + 0] = 0;
368 m[m_offset + 3 * 4 + 1] = 0;
369 m[m_offset + 3 * 4 + 2] = 0;
370 m[m_offset + 3 * 4 + 3] = 1;
372 makeTranslation(mat4Tmp,
true, -eye[0+eye_offset], -eye[1+eye_offset], -eye[2+eye_offset]);
416 final float x,
final float y,
417 final float deltaX,
final float deltaY,
418 final int[] viewport,
final int viewport_offset,
419 final float[] mat4Tmp) {
420 if (deltaX <= 0 || deltaY <= 0) {
426 (viewport[2+viewport_offset] - 2 * (x - viewport[0+viewport_offset])) / deltaX,
427 (viewport[3+viewport_offset] - 2 * (y - viewport[1+viewport_offset])) / deltaY,
430 viewport[2+viewport_offset] / deltaX, viewport[3+viewport_offset] / deltaY, 1.0f);
448 final int i4_1 = 1*4;
449 mres[0+i4_1] = msrc[1+0*4];
450 mres[1+i4_1] = msrc[1+1*4];
451 mres[2+i4_1] = msrc[1+2*4];
452 mres[3+i4_1] = msrc[1+3*4];
454 final int i4_2 = 2*4;
455 mres[0+i4_2] = msrc[2+0*4];
456 mres[1+i4_2] = msrc[2+1*4];
457 mres[2+i4_2] = msrc[2+2*4];
458 mres[3+i4_2] = msrc[2+3*4];
460 final int i4_3 = 3*4;
461 mres[0+i4_3] = msrc[3+0*4];
462 mres[1+i4_3] = msrc[3+1*4];
463 mres[2+i4_3] = msrc[3+2*4];
464 mres[3+i4_3] = msrc[3+3*4];
475 float a11 = m[ 1+4*1 ];
476 float a21 = m[ 2+4*1 ];
477 float a31 = m[ 3+4*1 ];
478 float a12 = m[ 1+4*2 ];
479 float a22 = m[ 2+4*2 ];
480 float a32 = m[ 3+4*2 ];
481 float a13 = m[ 1+4*3 ];
482 float a23 = m[ 2+4*3 ];
483 float a33 = m[ 3+4*3 ];
486 ret += m[ 0 ] * ( + a11*(a22*a33 - a23*a32) - a12*(a21*a33 - a23*a31) + a13*(a21*a32 - a22*a31));
490 ret -= m[ 0+4*1 ] * ( + a11*(a22*a33 - a23*a32) - a12*(a21*a33 - a23*a31) + a13*(a21*a32 - a22*a31));
494 ret += m[ 0+4*2 ] * ( + a11*(a22*a33 - a23*a32) - a12*(a21*a33 - a23*a31) + a13*(a21*a32 - a22*a31));
498 ret -= m[ 0+4*3 ] * ( + a11*(a22*a33 - a23*a32) - a12*(a21*a33 - a23*a31) + a13*(a21*a32 - a22*a31));
512 public static float[]
invertMatrix(
final float[] msrc,
final float[] mres) {
515 float max = Math.abs(msrc[0]);
517 for(
int i = 1; i < 16; i++ ) {
518 final float a = Math.abs(msrc[i]);
519 if( a > max ) max = a;
527 final float a11 = msrc[0+4*0]*scale;
528 final float a21 = msrc[1+4*0]*scale;
529 final float a31 = msrc[2+4*0]*scale;
530 final float a41 = msrc[3+4*0]*scale;
531 final float a12 = msrc[0+4*1]*scale;
532 final float a22 = msrc[1+4*1]*scale;
533 final float a32 = msrc[2+4*1]*scale;
534 final float a42 = msrc[3+4*1]*scale;
535 final float a13 = msrc[0+4*2]*scale;
536 final float a23 = msrc[1+4*2]*scale;
537 final float a33 = msrc[2+4*2]*scale;
538 final float a43 = msrc[3+4*2]*scale;
539 final float a14 = msrc[0+4*3]*scale;
540 final float a24 = msrc[1+4*3]*scale;
541 final float a34 = msrc[2+4*3]*scale;
542 final float a44 = msrc[3+4*3]*scale;
544 final float m11 = + a22*(a33*a44 - a34*a43) - a23*(a32*a44 - a34*a42) + a24*(a32*a43 - a33*a42);
545 final float m12 = -( + a21*(a33*a44 - a34*a43) - a23*(a31*a44 - a34*a41) + a24*(a31*a43 - a33*a41));
546 final float m13 = + a21*(a32*a44 - a34*a42) - a22*(a31*a44 - a34*a41) + a24*(a31*a42 - a32*a41);
547 final float m14 = -( + a21*(a32*a43 - a33*a42) - a22*(a31*a43 - a33*a41) + a23*(a31*a42 - a32*a41));
548 final float m21 = -( + a12*(a33*a44 - a34*a43) - a13*(a32*a44 - a34*a42) + a14*(a32*a43 - a33*a42));
549 final float m22 = + a11*(a33*a44 - a34*a43) - a13*(a31*a44 - a34*a41) + a14*(a31*a43 - a33*a41);
550 final float m23 = -( + a11*(a32*a44 - a34*a42) - a12*(a31*a44 - a34*a41) + a14*(a31*a42 - a32*a41));
551 final float m24 = + a11*(a32*a43 - a33*a42) - a12*(a31*a43 - a33*a41) + a13*(a31*a42 - a32*a41);
552 final float m31 = + a12*(a23*a44 - a24*a43) - a13*(a22*a44 - a24*a42) + a14*(a22*a43 - a23*a42);
553 final float m32 = -( + a11*(a23*a44 - a24*a43) - a13*(a21*a44 - a24*a41) + a14*(a21*a43 - a23*a41));
554 final float m33 = + a11*(a22*a44 - a24*a42) - a12*(a21*a44 - a24*a41) + a14*(a21*a42 - a22*a41);
555 final float m34 = -( + a11*(a22*a43 - a23*a42) - a12*(a21*a43 - a23*a41) + a13*(a21*a42 - a22*a41));
556 final float m41 = -( + a12*(a23*a34 - a24*a33) - a13*(a22*a34 - a24*a32) + a14*(a22*a33 - a23*a32));
557 final float m42 = + a11*(a23*a34 - a24*a33) - a13*(a21*a34 - a24*a31) + a14*(a21*a33 - a23*a31);
558 final float m43 = -( + a11*(a22*a34 - a24*a32) - a12*(a21*a34 - a24*a31) + a14*(a21*a32 - a22*a31));
559 final float m44 = + a11*(a22*a33 - a23*a32) - a12*(a21*a33 - a23*a31) + a13*(a21*a32 - a22*a31);
561 final float det = (a11*m11 + a12*m12 + a13*m13 + a14*m14)/scale;
565 final float invdet = 1.0f / det;
567 mres[0+4*0] = m11 * invdet;
568 mres[1+4*0] = m12 * invdet;
569 mres[2+4*0] = m13 * invdet;
570 mres[3+4*0] = m14 * invdet;
571 mres[0+4*1] = m21 * invdet;
572 mres[1+4*1] = m22 * invdet;
573 mres[2+4*1] = m23 * invdet;
574 mres[3+4*1] = m24 * invdet;
575 mres[0+4*2] = m31 * invdet;
576 mres[1+4*2] = m32 * invdet;
577 mres[2+4*2] = m33 * invdet;
578 mres[3+4*2] = m34 * invdet;
579 mres[0+4*3] = m41 * invdet;
580 mres[1+4*3] = m42 * invdet;
581 mres[2+4*3] = m43 * invdet;
582 mres[3+4*3] = m44 * invdet;
607 public static boolean mapObjToWin(
final float objx,
final float objy,
final float objz,
608 final float[] modelMatrix,
final int modelMatrix_offset,
609 final float[] projMatrix,
final int projMatrix_offset,
610 final int[] viewport,
final int viewport_offset,
611 final float[] win_pos,
final int win_pos_offset,
612 final float[] vec4Tmp1,
final float[] vec4Tmp2) {
622 multMatrixVec(modelMatrix, modelMatrix_offset, vec4Tmp1, 0, vec4Tmp2, 0);
623 multMatrixVec(projMatrix, projMatrix_offset, vec4Tmp2, 0, vec4Tmp1, 0);
625 if (vec4Tmp1[3] == 0.0f) {
629 vec4Tmp1[3] = (1.0f / vec4Tmp1[3]) * 0.5f;
632 vec4Tmp1[0] = vec4Tmp1[0] * vec4Tmp1[3] + 0.5f;
633 vec4Tmp1[1] = vec4Tmp1[1] * vec4Tmp1[3] + 0.5f;
634 vec4Tmp1[2] = vec4Tmp1[2] * vec4Tmp1[3] + 0.5f;
637 win_pos[0+win_pos_offset] = vec4Tmp1[0] * viewport[2+viewport_offset] + viewport[0+viewport_offset];
638 win_pos[1+win_pos_offset] = vec4Tmp1[1] * viewport[3+viewport_offset] + viewport[1+viewport_offset];
639 win_pos[2+win_pos_offset] = vec4Tmp1[2];
665 public static boolean mapWinToObj(
final float winx,
final float winy,
final float winz,
666 final float[] modelMatrix,
final int modelMatrix_offset,
667 final float[] projMatrix,
final int projMatrix_offset,
668 final int[] viewport,
final int viewport_offset,
669 final float[] obj_pos,
final int obj_pos_offset,
670 final float[] mat4Tmp1,
final float[] mat4Tmp2) {
672 multMatrix(projMatrix, projMatrix_offset, modelMatrix, modelMatrix_offset, mat4Tmp1, 0);
684 mat4Tmp2[0] = (mat4Tmp2[0] - viewport[0+viewport_offset]) / viewport[2+viewport_offset];
685 mat4Tmp2[1] = (mat4Tmp2[1] - viewport[1+viewport_offset]) / viewport[3+viewport_offset];
688 mat4Tmp2[0] = mat4Tmp2[0] * 2 - 1;
689 mat4Tmp2[1] = mat4Tmp2[1] * 2 - 1;
690 mat4Tmp2[2] = mat4Tmp2[2] * 2 - 1;
692 final int raw_off = 4;
696 if (mat4Tmp2[3+raw_off] == 0.0) {
700 mat4Tmp2[3+raw_off] = 1.0f / mat4Tmp2[3+raw_off];
702 obj_pos[0+obj_pos_offset] = mat4Tmp2[0+raw_off] * mat4Tmp2[3+raw_off];
703 obj_pos[1+obj_pos_offset] = mat4Tmp2[1+raw_off] * mat4Tmp2[3+raw_off];
704 obj_pos[2+obj_pos_offset] = mat4Tmp2[2+raw_off] * mat4Tmp2[3+raw_off];
733 public static boolean mapWinToObj4(
final float winx,
final float winy,
final float winz,
final float clipw,
734 final float[] modelMatrix,
final int modelMatrix_offset,
735 final float[] projMatrix,
final int projMatrix_offset,
736 final int[] viewport,
final int viewport_offset,
737 final float near,
final float far,
738 final float[] obj_pos,
final int obj_pos_offset,
739 final float[] mat4Tmp1,
final float[] mat4Tmp2) {
741 multMatrix(projMatrix, projMatrix_offset, modelMatrix, modelMatrix_offset, mat4Tmp1, 0);
754 mat4Tmp2[0] = (mat4Tmp2[0] - viewport[0+viewport_offset]) / viewport[2+viewport_offset];
755 mat4Tmp2[1] = (mat4Tmp2[1] - viewport[1+viewport_offset]) / viewport[3+viewport_offset];
756 mat4Tmp2[2] = (mat4Tmp2[2] - near) / (far - near);
759 mat4Tmp2[0] = mat4Tmp2[0] * 2 - 1;
760 mat4Tmp2[1] = mat4Tmp2[1] * 2 - 1;
761 mat4Tmp2[2] = mat4Tmp2[2] * 2 - 1;
763 final int raw_off = 4;
767 if (mat4Tmp2[3+raw_off] == 0.0) {
771 obj_pos[0+obj_pos_offset] = mat4Tmp2[0+raw_off];
772 obj_pos[1+obj_pos_offset] = mat4Tmp2[1+raw_off];
773 obj_pos[2+obj_pos_offset] = mat4Tmp2[2+raw_off];
774 obj_pos[3+obj_pos_offset] = mat4Tmp2[3+raw_off];
785 public static void multMatrix(
final float[] a,
final int a_off,
final float[] b,
final int b_off,
final float[] d,
final int d_off) {
786 final float b00 = b[b_off+0+0*4];
787 final float b10 = b[b_off+1+0*4];
788 final float b20 = b[b_off+2+0*4];
789 final float b30 = b[b_off+3+0*4];
790 final float b01 = b[b_off+0+1*4];
791 final float b11 = b[b_off+1+1*4];
792 final float b21 = b[b_off+2+1*4];
793 final float b31 = b[b_off+3+1*4];
794 final float b02 = b[b_off+0+2*4];
795 final float b12 = b[b_off+1+2*4];
796 final float b22 = b[b_off+2+2*4];
797 final float b32 = b[b_off+3+2*4];
798 final float b03 = b[b_off+0+3*4];
799 final float b13 = b[b_off+1+3*4];
800 final float b23 = b[b_off+2+3*4];
801 final float b33 = b[b_off+3+3*4];
803 float ai0=a[a_off+ 0*4];
804 float ai1=a[a_off+ 1*4];
805 float ai2=a[a_off+ 2*4];
806 float ai3=a[a_off+ 3*4];
807 d[d_off+ 0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
808 d[d_off+ 1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
809 d[d_off+ 2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
810 d[d_off+ 3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
816 d[d_off+1+0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
817 d[d_off+1+1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
818 d[d_off+1+2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
819 d[d_off+1+3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
825 d[d_off+2+0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
826 d[d_off+2+1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
827 d[d_off+2+2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
828 d[d_off+2+3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
834 d[d_off+3+0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
835 d[d_off+3+1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
836 d[d_off+3+2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
837 d[d_off+3+3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
847 public static float[]
multMatrix(
final float[] a,
final float[] b,
final float[] d) {
848 final float b00 = b[0+0*4];
849 final float b10 = b[1+0*4];
850 final float b20 = b[2+0*4];
851 final float b30 = b[3+0*4];
852 final float b01 = b[0+1*4];
853 final float b11 = b[1+1*4];
854 final float b21 = b[2+1*4];
855 final float b31 = b[3+1*4];
856 final float b02 = b[0+2*4];
857 final float b12 = b[1+2*4];
858 final float b22 = b[2+2*4];
859 final float b32 = b[3+2*4];
860 final float b03 = b[0+3*4];
861 final float b13 = b[1+3*4];
862 final float b23 = b[2+3*4];
863 final float b33 = b[3+3*4];
869 d[ 0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
870 d[ 1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
871 d[ 2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
872 d[ 3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
878 d[1+0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
879 d[1+1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
880 d[1+2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
881 d[1+3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
887 d[2+0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
888 d[2+1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
889 d[2+2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
890 d[2+3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
896 d[3+0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
897 d[3+1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
898 d[3+2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
899 d[3+3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
909 public static void multMatrix(
final float[] a,
final int a_off,
final float[] b,
final int b_off) {
910 final float b00 = b[b_off+0+0*4];
911 final float b10 = b[b_off+1+0*4];
912 final float b20 = b[b_off+2+0*4];
913 final float b30 = b[b_off+3+0*4];
914 final float b01 = b[b_off+0+1*4];
915 final float b11 = b[b_off+1+1*4];
916 final float b21 = b[b_off+2+1*4];
917 final float b31 = b[b_off+3+1*4];
918 final float b02 = b[b_off+0+2*4];
919 final float b12 = b[b_off+1+2*4];
920 final float b22 = b[b_off+2+2*4];
921 final float b32 = b[b_off+3+2*4];
922 final float b03 = b[b_off+0+3*4];
923 final float b13 = b[b_off+1+3*4];
924 final float b23 = b[b_off+2+3*4];
925 final float b33 = b[b_off+3+3*4];
927 float ai0=a[a_off+ 0*4];
928 float ai1=a[a_off+ 1*4];
929 float ai2=a[a_off+ 2*4];
930 float ai3=a[a_off+ 3*4];
931 a[a_off+ 0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
932 a[a_off+ 1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
933 a[a_off+ 2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
934 a[a_off+ 3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
940 a[a_off+1+0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
941 a[a_off+1+1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
942 a[a_off+1+2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
943 a[a_off+1+3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
949 a[a_off+2+0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
950 a[a_off+2+1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
951 a[a_off+2+2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
952 a[a_off+2+3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
958 a[a_off+3+0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
959 a[a_off+3+1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
960 a[a_off+3+2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
961 a[a_off+3+3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
970 public static float[]
multMatrix(
final float[] a,
final float[] b) {
971 final float b00 = b[0+0*4];
972 final float b10 = b[1+0*4];
973 final float b20 = b[2+0*4];
974 final float b30 = b[3+0*4];
975 final float b01 = b[0+1*4];
976 final float b11 = b[1+1*4];
977 final float b21 = b[2+1*4];
978 final float b31 = b[3+1*4];
979 final float b02 = b[0+2*4];
980 final float b12 = b[1+2*4];
981 final float b22 = b[2+2*4];
982 final float b32 = b[3+2*4];
983 final float b03 = b[0+3*4];
984 final float b13 = b[1+3*4];
985 final float b23 = b[2+3*4];
986 final float b33 = b[3+3*4];
992 a[ 0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
993 a[ 1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
994 a[ 2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
995 a[ 3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
1001 a[1+0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
1002 a[1+1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
1003 a[1+2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
1004 a[1+3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
1010 a[2+0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
1011 a[2+1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
1012 a[2+2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
1013 a[2+3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
1019 a[3+0*4] = ai0 * b00 + ai1 * b10 + ai2 * b20 + ai3 * b30 ;
1020 a[3+1*4] = ai0 * b01 + ai1 * b11 + ai2 * b21 + ai3 * b31 ;
1021 a[3+2*4] = ai0 * b02 + ai1 * b12 + ai2 * b22 + ai3 * b32 ;
1022 a[3+3*4] = ai0 * b03 + ai1 * b13 + ai2 * b23 + ai3 * b33 ;
1033 public static void multMatrix(
final FloatBuffer a,
final FloatBuffer b,
final float[] d) {
1034 final int a_off = a.position();
1035 final int b_off = b.position();
1036 for (
int i = 0; i < 4; i++) {
1038 final int a_off_i = a_off+i;
1039 final float ai0=a.get(a_off_i+0*4), ai1=a.get(a_off_i+1*4), ai2=a.get(a_off_i+2*4), ai3=a.get(a_off_i+3*4);
1040 d[i+0*4] = ai0 * b.get(b_off+0+0*4) + ai1 * b.get(b_off+1+0*4) + ai2 * b.get(b_off+2+0*4) + ai3 * b.get(b_off+3+0*4) ;
1041 d[i+1*4] = ai0 * b.get(b_off+0+1*4) + ai1 * b.get(b_off+1+1*4) + ai2 * b.get(b_off+2+1*4) + ai3 * b.get(b_off+3+1*4) ;
1042 d[i+2*4] = ai0 * b.get(b_off+0+2*4) + ai1 * b.get(b_off+1+2*4) + ai2 * b.get(b_off+2+2*4) + ai3 * b.get(b_off+3+2*4) ;
1043 d[i+3*4] = ai0 * b.get(b_off+0+3*4) + ai1 * b.get(b_off+1+3*4) + ai2 * b.get(b_off+2+3*4) + ai3 * b.get(b_off+3+3*4) ;
1052 public static void multMatrix(
final FloatBuffer a,
final FloatBuffer b) {
1053 final int a_off = a.position();
1054 final int b_off = b.position();
1055 for (
int i = 0; i < 4; i++) {
1057 final int a_off_i = a_off+i;
1058 final float ai0=a.get(a_off_i+0*4), ai1=a.get(a_off_i+1*4), ai2=a.get(a_off_i+2*4), ai3=a.get(a_off_i+3*4);
1059 a.put(a_off_i+0*4 , ai0 * b.get(b_off+0+0*4) + ai1 * b.get(b_off+1+0*4) + ai2 * b.get(b_off+2+0*4) + ai3 * b.get(b_off+3+0*4) );
1060 a.put(a_off_i+1*4 , ai0 * b.get(b_off+0+1*4) + ai1 * b.get(b_off+1+1*4) + ai2 * b.get(b_off+2+1*4) + ai3 * b.get(b_off+3+1*4) );
1061 a.put(a_off_i+2*4 , ai0 * b.get(b_off+0+2*4) + ai1 * b.get(b_off+1+2*4) + ai2 * b.get(b_off+2+2*4) + ai3 * b.get(b_off+3+2*4) );
1062 a.put(a_off_i+3*4 , ai0 * b.get(b_off+0+3*4) + ai1 * b.get(b_off+1+3*4) + ai2 * b.get(b_off+2+3*4) + ai3 * b.get(b_off+3+3*4) );
1073 final float[] v_in,
final int v_in_off,
1074 final float[] v_out,
final int v_out_off) {
1076 v_out[0 + v_out_off] = v_in[0+v_in_off] * m_in[0*4+m_in_off ] + v_in[1+v_in_off] * m_in[1*4+m_in_off ] +
1077 v_in[2+v_in_off] * m_in[2*4+m_in_off ] + v_in[3+v_in_off] * m_in[3*4+m_in_off ];
1079 final int m_in_off_1 = 1+m_in_off;
1080 v_out[1 + v_out_off] = v_in[0+v_in_off] * m_in[0*4+m_in_off_1] + v_in[1+v_in_off] * m_in[1*4+m_in_off_1] +
1081 v_in[2+v_in_off] * m_in[2*4+m_in_off_1] + v_in[3+v_in_off] * m_in[3*4+m_in_off_1];
1083 final int m_in_off_2 = 2+m_in_off;
1084 v_out[2 + v_out_off] = v_in[0+v_in_off] * m_in[0*4+m_in_off_2] + v_in[1+v_in_off] * m_in[1*4+m_in_off_2] +
1085 v_in[2+v_in_off] * m_in[2*4+m_in_off_2] + v_in[3+v_in_off] * m_in[3*4+m_in_off_2];
1087 final int m_in_off_3 = 3+m_in_off;
1088 v_out[3 + v_out_off] = v_in[0+v_in_off] * m_in[0*4+m_in_off_3] + v_in[1+v_in_off] * m_in[1*4+m_in_off_3] +
1089 v_in[2+v_in_off] * m_in[2*4+m_in_off_3] + v_in[3+v_in_off] * m_in[3*4+m_in_off_3];
1099 final float[] v_in,
final float[] v_out) {
1101 v_out[0] = v_in[0] * m_in[0*4+m_in_off ] + v_in[1] * m_in[1*4+m_in_off ] +
1102 v_in[2] * m_in[2*4+m_in_off ] + v_in[3] * m_in[3*4+m_in_off ];
1104 final int m_in_off_1 = 1+m_in_off;
1105 v_out[1] = v_in[0] * m_in[0*4+m_in_off_1] + v_in[1] * m_in[1*4+m_in_off_1] +
1106 v_in[2] * m_in[2*4+m_in_off_1] + v_in[3] * m_in[3*4+m_in_off_1];
1108 final int m_in_off_2 = 2+m_in_off;
1109 v_out[2] = v_in[0] * m_in[0*4+m_in_off_2] + v_in[1] * m_in[1*4+m_in_off_2] +
1110 v_in[2] * m_in[2*4+m_in_off_2] + v_in[3] * m_in[3*4+m_in_off_2];
1112 final int m_in_off_3 = 3+m_in_off;
1113 v_out[3] = v_in[0] * m_in[0*4+m_in_off_3] + v_in[1] * m_in[1*4+m_in_off_3] +
1114 v_in[2] * m_in[2*4+m_in_off_3] + v_in[3] * m_in[3*4+m_in_off_3];
1124 public static float[]
multMatrixVec(
final float[] m_in,
final float[] v_in,
final float[] v_out) {
1126 v_out[0] = v_in[0] * m_in[0*4 ] + v_in[1] * m_in[1*4 ] +
1127 v_in[2] * m_in[2*4 ] + v_in[3] * m_in[3*4 ];
1129 v_out[1] = v_in[0] * m_in[0*4+1] + v_in[1] * m_in[1*4+1] +
1130 v_in[2] * m_in[2*4+1] + v_in[3] * m_in[3*4+1];
1132 v_out[2] = v_in[0] * m_in[0*4+2] + v_in[1] * m_in[1*4+2] +
1133 v_in[2] * m_in[2*4+2] + v_in[3] * m_in[3*4+2];
1135 v_out[3] = v_in[0] * m_in[0*4+3] + v_in[1] * m_in[1*4+3] +
1136 v_in[2] * m_in[2*4+3] + v_in[3] * m_in[3*4+3];
1146 public static void multMatrixVec(
final FloatBuffer m_in,
final float[] v_in,
final float[] v_out) {
1147 final int m_in_off = m_in.position();
1148 for (
int i = 0; i < 4; i++) {
1150 final int i_m_in_off = i+m_in_off;
1152 v_in[0] * m_in.get(0*4+i_m_in_off) +
1153 v_in[1] * m_in.get(1*4+i_m_in_off) +
1154 v_in[2] * m_in.get(2*4+i_m_in_off) +
1155 v_in[3] * m_in.get(3*4+i_m_in_off);
1172 public static float[]
multMatrixVec3(
final float[] m_in,
final float[] v_in,
final float[] v_out) {
1174 v_out[0] = v_in[0] * m_in[0*4 ] + v_in[1] * m_in[1*4 ] +
1175 v_in[2] * m_in[2*4 ] + 1f * m_in[3*4 ];
1177 v_out[1] = v_in[0] * m_in[0*4+1] + v_in[1] * m_in[1*4+1] +
1178 v_in[2] * m_in[2*4+1] + 1f * m_in[3*4+1];
1180 v_out[2] = v_in[0] * m_in[0*4+2] + v_in[1] * m_in[1*4+2] +
1181 v_in[2] * m_in[2*4+2] + 1f * m_in[3*4+2];
1198 final FloatBuffer a,
final int aOffset,
1199 final int rows,
final int columns,
final boolean rowMajorOrder,
final int row) {
1201 sb =
new StringBuilder();
1203 final int a0 = aOffset + a.position();
1205 for(
int c=0; c<columns; c++) {
1206 sb.append( String.format((Locale)
null, f+
", ", a.get( a0 + row*columns + c ) ) );
1209 for(
int r=0; r<columns; r++) {
1210 sb.append( String.format((Locale)
null, f+
", ", a.get( a0 + row + r*rows ) ) );
1228 final float[] a,
final int aOffset,
final int rows,
final int columns,
final boolean rowMajorOrder,
final int row) {
1230 sb =
new StringBuilder();
1233 for(
int c=0; c<columns; c++) {
1234 sb.append( String.format((Locale)
null, f+
", ", a[ aOffset + row*columns + c ] ) );
1237 for(
int r=0; r<columns; r++) {
1238 sb.append( String.format((Locale)
null, f+
", ", a[ aOffset + row + r*rows ] ) );
1255 public static StringBuilder
matrixToString(StringBuilder sb,
final String rowPrefix,
final String f,
1256 final FloatBuffer a,
final int aOffset,
final int rows,
final int columns,
final boolean rowMajorOrder) {
1258 sb =
new StringBuilder();
1260 final String prefix = (
null == rowPrefix ) ?
"" : rowPrefix;
1261 sb.append(prefix).append(
"{ ");
1262 for(
int i=0; i<rows; i++) {
1264 sb.append(prefix).append(
" ");
1267 sb.append(System.lineSeparator());
1269 sb.append(prefix).append(
"}").append(System.lineSeparator());
1284 public static StringBuilder
matrixToString(StringBuilder sb,
final String rowPrefix,
final String f,
1285 final float[] a,
final int aOffset,
final int rows,
final int columns,
final boolean rowMajorOrder) {
1287 sb =
new StringBuilder();
1289 final String prefix = (
null == rowPrefix ) ?
"" : rowPrefix;
1290 sb.append(prefix).append(
"{ ");
1291 for(
int i=0; i<rows; i++) {
1293 sb.append(prefix).append(
" ");
1296 sb.append(System.lineSeparator());
1298 sb.append(prefix).append(
"}").append(System.lineSeparator());
1306 @SuppressWarnings(
"unused")
1307 private static
void calculateMachineEpsilonFloat() {
1309 if( DEBUG_EPSILON ) {
1310 t0 = Platform.currentTimeMillis();
1312 float machEps = 1.0f;
1317 }
while (1.0f + (machEps / 2.0f) != 1.0f);
1318 machEpsilon = machEps;
1319 if( DEBUG_EPSILON ) {
1320 final long t1 = Platform.currentTimeMillis();
1321 System.err.println(
"MachineEpsilon: "+machEpsilon+
", in "+i+
" iterations within "+(t1-t0)+
" ms");
1324 private static volatile boolean machEpsilonAvail =
false;
1325 private static float machEpsilon = 0f;
1326 private static final boolean DEBUG_EPSILON =
false;
1339 if( !machEpsilonAvail ) {
1341 if( !machEpsilonAvail ) {
1342 machEpsilonAvail =
true;
1343 calculateMachineEpsilonFloat();
1350 public static final float E = 2.7182818284590452354f;
1353 public static final float PI = 3.14159265358979323846f;
1369 return arc_degree *
PI / 180.0f;
1374 return rad * 180.0f /
PI;
1403 public static final float EPSILON = 1.1920929E-7f;
1431 return Float.floatToIntBits(a) == Float.floatToIntBits(b);
1450 public static boolean isEqual(
final float a,
final float b,
final float epsilon) {
1451 if( Math.abs(a - b) < epsilon ) {
1455 return Float.floatToIntBits(a) == Float.floatToIntBits(b);
1472 public static boolean isEqual(
final float a,
final float b) {
1473 if ( Math.abs(a - b) <
EPSILON ) {
1477 return Float.floatToIntBits(a) == Float.floatToIntBits(b);
1489 public static boolean isEqual2(
final float a,
final float b) {
1490 return Math.abs(a - b) <
EPSILON;
1508 public static int compare(
final float a,
final float b) {
1515 final int aBits = Float.floatToIntBits(a);
1516 final int bBits = Float.floatToIntBits(b);
1517 if( aBits == bBits ) {
1519 }
else if( aBits < bBits ) {
1544 public static int compare(
final float a,
final float b,
final float epsilon) {
1545 if( Math.abs(a - b) < epsilon ) {
1561 public static boolean isZero(
final float a,
final float epsilon) {
1562 return Math.abs(a) < epsilon;
1569 public static boolean isZero(
final float a) {
1597 public static float abs(
final float a) {
return java.lang.Math.abs(a); }
1599 public static float pow(
final float a,
final float b) {
return (
float) java.lang.Math.pow(a, b); }
1601 public static float sin(
final float a) {
return (
float) java.lang.Math.sin(a); }
1603 public static float asin(
final float a) {
return (
float) java.lang.Math.asin(a); }
1605 public static float cos(
final float a) {
return (
float) java.lang.Math.cos(a); }
1607 public static float acos(
final float a) {
return (
float) java.lang.Math.acos(a); }
1609 public static float tan(
final float a) {
return (
float) java.lang.Math.tan(a); }
1611 public static float atan(
final float a) {
return (
float) java.lang.Math.atan(a); }
1613 public static float atan2(
final float y,
final float x) {
return (
float) java.lang.Math.atan2(y, x); }
1615 public static float sqrt(
final float a) {
return (
float) java.lang.Math.sqrt(a); }
1634 return z * z / ( zNear * ( 1 << zBits ) - z );
1651 public static int getZBufferValue(
final int zBits,
final float z,
final float zNear,
final float zFar) {
1652 final float a = zFar / ( zFar - zNear );
1653 final float b = zFar * zNear / ( zNear - zFar );
1654 return (
int) ( (1<<zBits) * ( a + b / z ) );
1661 public static float getOrthoWinZ(
final float orthoZ,
final float zNear,
final float zFar) {
1662 return (1f/zNear-1f/orthoZ) / (1f/zNear-1f/zFar);
Basic Float math utility functions.
static boolean isEqualRaw(final float a, final float b)
Returns true if both values are equal disregarding EPSILON but considering NaN, -Inf and +Inf.
static int compare(final float a, final float b)
Returns -1, 0 or 1 if a is less, equal or greater than b, disregarding epsilon but considering NaN,...
static boolean mapWinToObj4(final float winx, final float winy, final float winz, final float clipw, final float[] modelMatrix, final int modelMatrix_offset, final float[] projMatrix, final int projMatrix_offset, final int[] viewport, final int viewport_offset, final float near, final float far, final float[] obj_pos, final int obj_pos_offset, final float[] mat4Tmp1, final float[] mat4Tmp2)
Map window coordinates to object coordinates.
static float getOrthoWinZ(final float orthoZ, final float zNear, final float zFar)
Returns orthogonal distance (1f/zNear-1f/orthoZ) / (1f/zNear-1f/zFar);.
static final float TWO_PI
The value 2PI, i.e.
static float getZBufferEpsilon(final int zBits, final float z, final float zNear)
Returns resolution of Z buffer of given parameter, see Love Your Z-Buffer.
static float acos(final float a)
static float sin(final float a)
static float[] makeLookAt(final float[] m, final int m_offset, final float[] eye, final int eye_offset, final float[] center, final int center_offset, final float[] up, final int up_offset, final float[] mat4Tmp)
Make given matrix the look-at matrix based on given parameters.
static final float QUARTER_PI
The value PI/4, i.e.
static float atan(final float a)
static boolean mapObjToWin(final float objx, final float objy, final float objz, final float[] modelMatrix, final int modelMatrix_offset, final float[] projMatrix, final int projMatrix_offset, final int[] viewport, final int viewport_offset, final float[] win_pos, final int win_pos_offset, final float[] vec4Tmp1, final float[] vec4Tmp2)
Map object coordinates to window coordinates.
static boolean isZero(final float a)
Returns true if value is zero, i.e.
static final int IEC559_SIGN_BIT
Signed bit 31 of IEEE 754 (IEC 559) single float-point bit layout, i.e.
static float[] makeScale(final float[] m, final boolean initM, final float sx, final float sy, final float sz)
Make a scale matrix in column-major order from the given axis factors.
static final float PI
The value PI, i.e.
static void multMatrix(final FloatBuffer a, final FloatBuffer b)
Multiply matrix: [a] = [a] x [b].
static float[] makePerspective(final float[] m, final int m_off, final boolean initM, final float fovy_rad, final float aspect, final float zNear, final float zFar)
Make given matrix the perspective frustum matrix based on given parameters.
static float atan2(final float y, final float x)
static boolean mapWinToObj(final float winx, final float winy, final float winz, final float[] modelMatrix, final int modelMatrix_offset, final float[] projMatrix, final int projMatrix_offset, final int[] viewport, final int viewport_offset, final float[] obj_pos, final int obj_pos_offset, final float[] mat4Tmp1, final float[] mat4Tmp2)
Map window coordinates to object coordinates.
static boolean isEqual2(final float a, final float b)
Returns true if both values are equal, i.e.
static final float EPSILON
Epsilon for floating point {@value}, as once computed via getMachineEpsilon() on an AMD-64 CPU.
static StringBuilder matrixRowToString(StringBuilder sb, final String f, final FloatBuffer a, final int aOffset, final int rows, final int columns, final boolean rowMajorOrder, final int row)
static final float INV_DEVIANCE
Inversion Epsilon, used with equals method to determine if two inverted matrices are close enough to ...
static void multMatrixVec(final float[] m_in, final int m_in_off, final float[] v_in, final int v_in_off, final float[] v_out, final int v_out_off)
static float[] multMatrix(final float[] a, final float[] b)
Multiply matrix: [a] = [a] x [b].
static float abs(final float a)
Invokes Math#abs(float).
static float[] makeFrustum(final float[] m, final int m_offset, final boolean initM, final float left, final float right, final float bottom, final float top, final float zNear, final float zFar)
Make given matrix the frustum matrix based on given parameters.
static void multMatrix(final float[] a, final int a_off, final float[] b, final int b_off, final float[] d, final int d_off)
Multiply matrix: [d] = [a] x [b].
static float matrixDeterminant(final float[] m)
Returns the determinant of the given matrix.
static boolean isEqual(final float a, final float b)
Returns true if both values are equal, i.e.
static float[] makePick(final float[] m, final float x, final float y, final float deltaX, final float deltaY, final int[] viewport, final int viewport_offset, final float[] mat4Tmp)
Make given matrix the pick matrix based on given parameters.
static boolean isZeroRaw(final float a)
Returns true if value is zero, disregarding EPSILON but considering NaN, -Inf and +Inf.
static void multMatrixVec(final FloatBuffer m_in, final float[] v_in, final float[] v_out)
static float radToADeg(final float rad)
Converts radians to arc-degree.
static StringBuilder matrixRowToString(StringBuilder sb, final String f, final float[] a, final int aOffset, final int rows, final int columns, final boolean rowMajorOrder, final int row)
static float cos(final float a)
static float tan(final float a)
static StringBuilder matrixToString(StringBuilder sb, final String rowPrefix, final String f, final FloatBuffer a, final int aOffset, final int rows, final int columns, final boolean rowMajorOrder)
static float asin(final float a)
static float[] multMatrixVec3(final float[] m_in, final float[] v_in, final float[] v_out)
Affine 3f-vector transformation by 4x4 matrix.
static void multMatrixVec(final float[] m_in, final int m_in_off, final float[] v_in, final float[] v_out)
static float[] transposeMatrix(final float[] msrc, final float[] mres)
Transpose the given matrix.
static void multMatrix(final float[] a, final int a_off, final float[] b, final int b_off)
Multiply matrix: [a] = [a] x [b].
static float getMachineEpsilon()
Return computed machine Epsilon value.
static void multMatrix(final FloatBuffer a, final FloatBuffer b, final float[] d)
Multiply matrix: [d] = [a] x [b].
static float[] multMatrix(final float[] a, final float[] b, final float[] d)
Multiply matrix: [d] = [a] x [b].
static float adegToRad(final float arc_degree)
Converts arc-degree to radians.
static boolean isZero(final float a, final float epsilon)
Returns true if value is zero, i.e.
static final float SQUARED_PI
The value PI^2.
static int getZBufferValue(final int zBits, final float z, final float zNear, final float zFar)
Returns Z buffer value of given parameter, see Love Your Z-Buffer.
static float[] invertMatrix(final float[] msrc, final float[] mres)
Invert the given matrix.
static boolean isEqual(final float a, final float b, final float epsilon)
Returns true if both values are equal, i.e.
static float[] makeTranslation(final float[] m, final boolean initM, final float tx, final float ty, final float tz)
Make a translation matrix in column-major order from the given axis deltas.
static float[] makeIdentity(final float[] m)
Make matrix an identity matrix.
static final float HALF_PI
The value PI/2, i.e.
static float sqrt(final float a)
static StringBuilder matrixToString(StringBuilder sb, final String rowPrefix, final String f, final float[] a, final int aOffset, final int rows, final int columns, final boolean rowMajorOrder)
static int compare(final float a, final float b, final float epsilon)
Returns -1, 0 or 1 if a is less, equal or greater than b, considering epsilon and NaN,...
static float[] multMatrixVec(final float[] m_in, final float[] v_in, final float[] v_out)
static final boolean DEBUG
static float pow(final float a, final float b)
static float[] crossVec3(final float[] r, final int r_offset, final float[] v1, final int v1_offset, final float[] v2, final int v2_offset)
cross product vec1 x vec2
static float[] normalizeVec3(final float[] vector)
Normalize a vector in place.
A generic exception for OpenGL errors used throughout the binding as a substitute for RuntimeExceptio...