summaryrefslogtreecommitdiffstats
path: root/src/mesa/math/m_norm_tmp.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/math/m_norm_tmp.h')
-rw-r--r--src/mesa/math/m_norm_tmp.h413
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);
+}