diff options
Diffstat (limited to 'src/mesa/math/m_norm_tmp.h')
-rw-r--r-- | src/mesa/math/m_norm_tmp.h | 413 |
1 files changed, 413 insertions, 0 deletions
diff --git a/src/mesa/math/m_norm_tmp.h b/src/mesa/math/m_norm_tmp.h new file mode 100644 index 00000000000..72770c2075e --- /dev/null +++ b/src/mesa/math/m_norm_tmp.h @@ -0,0 +1,413 @@ +/* $Id: m_norm_tmp.h,v 1.1 2000/11/16 21:05:41 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.3 + * + * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * New (3.1) transformation code written by Keith Whitwell. + */ + + +static void _XFORMAPI +TAG(transform_normalize_normals)( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + const GLubyte mask[], + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *from = in->start; + GLuint stride = in->stride; + GLuint count = in->count; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + GLfloat *m = mat->inv; + GLfloat m0 = m[0], m4 = m[4], m8 = m[8]; + GLfloat m1 = m[1], m5 = m[5], m9 = m[9]; + GLfloat m2 = m[2], m6 = m[6], m10 = m[10]; + + (void) mask; + if (!lengths) { + STRIDE_LOOP { + CULL_CHECK { + GLfloat tx, ty, tz; + { + const GLfloat ux = from[0], uy = from[1], uz = from[2]; + tx = ux * m0 + uy * m1 + uz * m2; + ty = ux * m4 + uy * m5 + uz * m6; + tz = ux * m8 + uy * m9 + uz * m10; + } + { + GLdouble len = tx*tx + ty*ty + tz*tz; + if (len > 1e-20) { + GLdouble scale = 1.0 / GL_SQRT(len); + out[i][0] = (GLfloat) (tx * scale); + out[i][1] = (GLfloat) (ty * scale); + out[i][2] = (GLfloat) (tz * scale); + } + else + { + out[i][0] = out[i][1] = out[i][2] = 0; + } + } + } + } + } + else { + /* scale has been snapped to 1.0 if it is close. + */ + if (scale != 1.0) { + m0 *= scale, m4 *= scale, m8 *= scale; + m1 *= scale, m5 *= scale, m9 *= scale; + m2 *= scale, m6 *= scale, m10 *= scale; + } + + STRIDE_LOOP { + CULL_CHECK { + GLfloat tx, ty, tz; + { + const GLfloat ux = from[0], uy = from[1], uz = from[2]; + tx = ux * m0 + uy * m1 + uz * m2; + ty = ux * m4 + uy * m5 + uz * m6; + tz = ux * m8 + uy * m9 + uz * m10; + } + { + GLfloat len = lengths[i]; + out[i][0] = tx * len; + out[i][1] = ty * len; + out[i][2] = tz * len; + } + } + } + } + dest->count = in->count; +} + + +static void _XFORMAPI +TAG(transform_normalize_normals_no_rot)( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + const GLubyte mask[], + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *from = in->start; + GLuint stride = in->stride; + GLuint count = in->count; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + GLfloat *m = mat->inv; + GLfloat m0 = m[0]; + GLfloat m5 = m[5]; + GLfloat m10 = m[10]; + (void) mask; + if (!lengths) { + STRIDE_LOOP { + CULL_CHECK { + GLfloat tx, ty, tz; + { + const GLfloat ux = from[0], uy = from[1], uz = from[2]; + tx = ux * m0 ; + ty = uy * m5 ; + tz = uz * m10; + } + { + GLdouble len = tx*tx + ty*ty + tz*tz; + if (len > 1e-20) { + GLdouble scale = 1.0 / GL_SQRT(len); + out[i][0] = (GLfloat) (tx * scale); + out[i][1] = (GLfloat) (ty * scale); + out[i][2] = (GLfloat) (tz * scale); + } + else + { + out[i][0] = out[i][1] = out[i][2] = 0; + } + } + } + } + } + else { + /* scale has been snapped to 1.0 if it is close. + */ + if (scale != 1.0) { + m0 *= scale; + m5 *= scale; + m10 *= scale; + } + + STRIDE_LOOP { + CULL_CHECK { + GLfloat tx, ty, tz; + { + const GLfloat ux = from[0], uy = from[1], uz = from[2]; + tx = ux * m0 ; + ty = uy * m5 ; + tz = uz * m10; + } + { + GLfloat len = lengths[i]; + out[i][0] = tx * len; + out[i][1] = ty * len; + out[i][2] = tz * len; + } + } + } + } + dest->count = in->count; +} + + +static void _XFORMAPI +TAG(transform_rescale_normals_no_rot)( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + const GLubyte mask[], + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *from = in->start; + GLuint stride = in->stride; + GLuint count = in->count; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + const GLfloat *m = mat->inv; + GLfloat m0 = scale*m[0]; + GLfloat m5 = scale*m[5]; + GLfloat m10 = scale*m[10]; + (void) lengths; + (void) mask; + STRIDE_LOOP { + CULL_CHECK { + GLfloat ux = from[0], uy = from[1], uz = from[2]; + out[i][0] = ux * m0; + out[i][1] = uy * m5; + out[i][2] = uz * m10; + } + } + dest->count = in->count; +} + +static void _XFORMAPI +TAG(transform_rescale_normals)( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + const GLubyte mask[], + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *from = in->start; + GLuint stride = in->stride; + GLuint count = in->count; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + /* Since we are unlikely to have < 3 vertices in the buffer, + * it makes sense to pre-multiply by scale. + */ + const GLfloat *m = mat->inv; + GLfloat m0 = scale*m[0], m4 = scale*m[4], m8 = scale*m[8]; + GLfloat m1 = scale*m[1], m5 = scale*m[5], m9 = scale*m[9]; + GLfloat m2 = scale*m[2], m6 = scale*m[6], m10 = scale*m[10]; + (void) lengths; + (void) mask; + STRIDE_LOOP { + CULL_CHECK { + GLfloat ux = from[0], uy = from[1], uz = from[2]; + out[i][0] = ux * m0 + uy * m1 + uz * m2; + out[i][1] = ux * m4 + uy * m5 + uz * m6; + out[i][2] = ux * m8 + uy * m9 + uz * m10; + } + } + dest->count = in->count; +} + + +static void _XFORMAPI +TAG(transform_normals_no_rot)(const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + const GLubyte mask[], + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *from = in->start; + GLuint stride = in->stride; + GLuint count = in->count; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + const GLfloat *m = mat->inv; + GLfloat m0 = m[0]; + GLfloat m5 = m[5]; + GLfloat m10 = m[10]; + (void) scale; + (void) lengths; + (void) mask; + STRIDE_LOOP { + CULL_CHECK { + GLfloat ux = from[0], uy = from[1], uz = from[2]; + out[i][0] = ux * m0; + out[i][1] = uy * m5; + out[i][2] = uz * m10; + } + } + dest->count = in->count; +} + + +static void _XFORMAPI +TAG(transform_normals)( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + const GLubyte mask[], + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *from = in->start; + GLuint stride = in->stride; + GLuint count = in->count; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + const GLfloat *m = mat->inv; + GLfloat m0 = m[0], m4 = m[4], m8 = m[8]; + GLfloat m1 = m[1], m5 = m[5], m9 = m[9]; + GLfloat m2 = m[2], m6 = m[6], m10 = m[10]; + (void) scale; + (void) lengths; + (void) mask; + STRIDE_LOOP { + CULL_CHECK { + GLfloat ux = from[0], uy = from[1], uz = from[2]; + out[i][0] = ux * m0 + uy * m1 + uz * m2; + out[i][1] = ux * m4 + uy * m5 + uz * m6; + out[i][2] = ux * m8 + uy * m9 + uz * m10; + } + } + dest->count = in->count; +} + + +static void _XFORMAPI +TAG(normalize_normals)( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + const GLubyte mask[], + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *from = in->start; + GLuint stride = in->stride; + GLuint count = in->count; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + (void) mat; + (void) mask; + (void) scale; + if (lengths) { + STRIDE_LOOP { + CULL_CHECK { + const GLfloat x = from[0], y = from[1], z = from[2]; + GLfloat invlen = lengths[i]; + out[i][0] = x * invlen; + out[i][1] = y * invlen; + out[i][2] = z * invlen; + } + } + } + else { + STRIDE_LOOP { + CULL_CHECK { + const GLfloat x = from[0], y = from[1], z = from[2]; + GLdouble len = x * x + y * y + z * z; + if (len > 1e-50) { + len = 1.0 / GL_SQRT(len); + out[i][0] = (GLfloat) (x * len); + out[i][1] = (GLfloat) (y * len); + out[i][2] = (GLfloat) (z * len); + } + else { + out[i][0] = x; + out[i][1] = y; + out[i][2] = z; + } + } + } + } + dest->count = in->count; +} + + +static void _XFORMAPI +TAG(rescale_normals)( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + const GLubyte mask[], + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *from = in->start; + GLuint stride = in->stride; + GLuint count = in->count; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + (void) mat; + (void) lengths; + (void) mask; + + STRIDE_LOOP { + CULL_CHECK { + SCALE_SCALAR_3V( out[i], scale, from ); + } + } + dest->count = in->count; +} + + +static void _XFORMAPI +TAG(init_c_norm_transform)( void ) +{ + gl_normal_tab[NORM_TRANSFORM_NO_ROT][IDX] = + TAG(transform_normals_no_rot); + + gl_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_RESCALE][IDX] = + TAG(transform_rescale_normals_no_rot); + + gl_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE][IDX] = + TAG(transform_normalize_normals_no_rot); + + gl_normal_tab[NORM_TRANSFORM][IDX] = + TAG(transform_normals); + + gl_normal_tab[NORM_TRANSFORM | NORM_RESCALE][IDX] = + TAG(transform_rescale_normals); + + gl_normal_tab[NORM_TRANSFORM | NORM_NORMALIZE][IDX] = + TAG(transform_normalize_normals); + + gl_normal_tab[NORM_RESCALE][IDX] = + TAG(rescale_normals); + + gl_normal_tab[NORM_NORMALIZE][IDX] = + TAG(normalize_normals); +} |