home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / math / m_norm_tmp.h < prev    next >
Text File  |  2002-10-24  |  12KB  |  392 lines

  1. /* $Id: m_norm_tmp.h,v 1.12 2002/10/24 23:57:24 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  4.1
  6.  *
  7.  * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  8.  *
  9.  * Permission is hereby granted, free of charge, to any person obtaining a
  10.  * copy of this software and associated documentation files (the "Software"),
  11.  * to deal in the Software without restriction, including without limitation
  12.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13.  * and/or sell copies of the Software, and to permit persons to whom the
  14.  * Software is furnished to do so, subject to the following conditions:
  15.  *
  16.  * The above copyright notice and this permission notice shall be included
  17.  * in all copies or substantial portions of the Software.
  18.  *
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  23.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  */
  26.  
  27. /*
  28.  * New (3.1) transformation code written by Keith Whitwell.
  29.  */
  30.  
  31. /* Functions to tranform a vector of normals.  This includes applying
  32.  * the transformation matrix, rescaling and normalization.
  33.  */
  34.  
  35. /*
  36.  * mat - the 4x4 transformation matrix
  37.  * scale - uniform scale factor of the transformation matrix (not always used)
  38.  * in - the source vector of normals
  39.  * lengths - length of each incoming normal (may be NULL) (a display list
  40.  *           optimization)
  41.  * dest - the destination vector of normals
  42.  */
  43. static void _XFORMAPI
  44. TAG(transform_normalize_normals)( const GLmatrix *mat,
  45.                                   GLfloat scale,
  46.                                   const GLvector4f *in,
  47.                                   const GLfloat *lengths,
  48.                                   GLvector4f *dest )
  49. {
  50.    GLfloat (*out)[4] = (GLfloat (*)[4])dest->start;
  51.    const GLfloat *from = in->start;
  52.    const GLuint stride = in->stride;
  53.    const GLuint count = in->count;
  54.    const GLfloat *m = mat->inv;
  55.    GLfloat m0 = m[0],  m4 = m[4],  m8 = m[8];
  56.    GLfloat m1 = m[1],  m5 = m[5],  m9 = m[9];
  57.    GLfloat m2 = m[2],  m6 = m[6],  m10 = m[10];
  58.    GLuint i;
  59.  
  60.    if (!lengths) {
  61.       STRIDE_LOOP {
  62.      GLfloat tx, ty, tz;
  63.      {
  64.         const GLfloat ux = from[0],  uy = from[1],  uz = from[2];
  65.         tx = ux * m0 + uy * m1 + uz * m2;
  66.         ty = ux * m4 + uy * m5 + uz * m6;
  67.         tz = ux * m8 + uy * m9 + uz * m10;
  68.      }
  69.      {
  70.         GLdouble len = tx*tx + ty*ty + tz*tz;
  71.         if (len > 1e-20) {
  72.            GLdouble scale = 1.0 / GL_SQRT(len);
  73.            out[i][0] = (GLfloat) (tx * scale);
  74.            out[i][1] = (GLfloat) (ty * scale);
  75.            out[i][2] = (GLfloat) (tz * scale);
  76.         }
  77.         else {
  78.            out[i][0] = out[i][1] = out[i][2] = 0;
  79.         }
  80.      }
  81.       }
  82.    }
  83.    else {
  84.       if (scale != 1.0) {
  85.      m0 *= scale,  m4 *= scale,  m8 *= scale;
  86.      m1 *= scale,  m5 *= scale,  m9 *= scale;
  87.      m2 *= scale,  m6 *= scale,  m10 *= scale;
  88.       }
  89.  
  90.       STRIDE_LOOP {
  91.      GLfloat tx, ty, tz;
  92.      {
  93.         const GLfloat ux = from[0],  uy = from[1],  uz = from[2];
  94.         tx = ux * m0 + uy * m1 + uz * m2;
  95.         ty = ux * m4 + uy * m5 + uz * m6;
  96.         tz = ux * m8 + uy * m9 + uz * m10;
  97.      }
  98.      {
  99.         GLfloat len = lengths[i];
  100.         out[i][0] = tx * len;
  101.         out[i][1] = ty * len;
  102.         out[i][2] = tz * len;
  103.      }
  104.       }
  105.    }
  106.    dest->count = in->count;
  107. }
  108.  
  109.  
  110. static void _XFORMAPI
  111. TAG(transform_normalize_normals_no_rot)( const GLmatrix *mat,
  112.                                          GLfloat scale,
  113.                                          const GLvector4f *in,
  114.                                          const GLfloat *lengths,
  115.                                          GLvector4f *dest )
  116. {
  117.    GLfloat (*out)[4] = (GLfloat (*)[4])dest->start;
  118.    const GLfloat *from = in->start;
  119.    const GLuint stride = in->stride;
  120.    const GLuint count = in->count;
  121.    const GLfloat *m = mat->inv;
  122.    GLfloat m0 = m[0];
  123.    GLfloat m5 = m[5];
  124.    GLfloat m10 = m[10];
  125.    GLuint i;
  126.  
  127.    if (!lengths) {
  128.       STRIDE_LOOP {
  129.      GLfloat tx, ty, tz;
  130.      {
  131.         const GLfloat ux = from[0],  uy = from[1],  uz = from[2];
  132.         tx = ux * m0                    ;
  133.         ty =           uy * m5          ;
  134.         tz =                     uz * m10;
  135.      }
  136.      {
  137.         GLdouble len = tx*tx + ty*ty + tz*tz;
  138.         if (len > 1e-20) {
  139.            GLdouble scale = 1.0 / GL_SQRT(len);
  140.            out[i][0] = (GLfloat) (tx * scale);
  141.            out[i][1] = (GLfloat) (ty * scale);
  142.            out[i][2] = (GLfloat) (tz * scale);
  143.         }
  144.         else {
  145.            out[i][0] = out[i][1] = out[i][2] = 0;
  146.         }
  147.      }
  148.       }
  149.    }
  150.    else {
  151.       m0 *= scale;
  152.       m5 *= scale;
  153.       m10 *= scale;
  154.  
  155.       STRIDE_LOOP {
  156.      GLfloat tx, ty, tz;
  157.      {
  158.         const GLfloat ux = from[0],  uy = from[1],  uz = from[2];
  159.         tx = ux * m0                    ;
  160.         ty =           uy * m5          ;
  161.         tz =                     uz * m10;
  162.      }
  163.      {
  164.         GLfloat len = lengths[i];
  165.         out[i][0] = tx * len;
  166.         out[i][1] = ty * len;
  167.         out[i][2] = tz * len;
  168.      }
  169.       }
  170.    }
  171.    dest->count = in->count;
  172. }
  173.  
  174.  
  175. static void _XFORMAPI
  176. TAG(transform_rescale_normals_no_rot)( const GLmatrix *mat,
  177.                                        GLfloat scale,
  178.                                        const GLvector4f *in,
  179.                                        const GLfloat *lengths,
  180.                                        GLvector4f *dest )
  181. {
  182.    GLfloat (*out)[4] = (GLfloat (*)[4])dest->start;
  183.    const GLfloat *from = in->start;
  184.    const GLuint stride = in->stride;
  185.    const GLuint count = in->count;
  186.    const GLfloat *m = mat->inv;
  187.    const GLfloat m0 = scale*m[0];
  188.    const GLfloat m5 = scale*m[5];
  189.    const GLfloat m10 = scale*m[10];
  190.    GLuint i;
  191.  
  192.    (void) lengths;
  193.  
  194.    STRIDE_LOOP {
  195.       GLfloat ux = from[0],  uy = from[1],  uz = from[2];
  196.       out[i][0] = ux * m0;
  197.       out[i][1] =           uy * m5;
  198.       out[i][2] =                     uz * m10;
  199.    }
  200.    dest->count = in->count;
  201. }
  202.  
  203.  
  204. static void _XFORMAPI
  205. TAG(transform_rescale_normals)( const GLmatrix *mat,
  206.                                 GLfloat scale,
  207.                                 const GLvector4f *in,
  208.                                 const GLfloat *lengths,
  209.                                 GLvector4f *dest )
  210. {
  211.    GLfloat (*out)[4] = (GLfloat (*)[4])dest->start;
  212.    const GLfloat *from = in->start;
  213.    const GLuint stride = in->stride;
  214.    const GLuint count = in->count;
  215.    /* Since we are unlikely to have < 3 vertices in the buffer,
  216.     * it makes sense to pre-multiply by scale.
  217.     */
  218.    const GLfloat *m = mat->inv;
  219.    const GLfloat m0 = scale*m[0],  m4 = scale*m[4],  m8 = scale*m[8];
  220.    const GLfloat m1 = scale*m[1],  m5 = scale*m[5],  m9 = scale*m[9];
  221.    const GLfloat m2 = scale*m[2],  m6 = scale*m[6],  m10 = scale*m[10];
  222.    GLuint i;
  223.  
  224.    (void) lengths;
  225.  
  226.    STRIDE_LOOP {
  227.       GLfloat ux = from[0],  uy = from[1],  uz = from[2];
  228.       out[i][0] = ux * m0 + uy * m1 + uz * m2;
  229.       out[i][1] = ux * m4 + uy * m5 + uz * m6;
  230.       out[i][2] = ux * m8 + uy * m9 + uz * m10;
  231.    }
  232.    dest->count = in->count;
  233. }
  234.  
  235.  
  236. static void _XFORMAPI
  237. TAG(transform_normals_no_rot)( const GLmatrix *mat,
  238.                    GLfloat scale,
  239.                    const GLvector4f *in,
  240.                    const GLfloat *lengths,
  241.                    GLvector4f *dest )
  242. {
  243.    GLfloat (*out)[4] = (GLfloat (*)[4])dest->start;
  244.    const GLfloat *from = in->start;
  245.    const GLuint stride = in->stride;
  246.    const GLuint count = in->count;
  247.    const GLfloat *m = mat->inv;
  248.    const GLfloat m0 = m[0];
  249.    const GLfloat m5 = m[5];
  250.    const GLfloat m10 = m[10];
  251.    GLuint i;
  252.  
  253.    (void) scale;
  254.    (void) lengths;
  255.  
  256.    STRIDE_LOOP {
  257.       GLfloat ux = from[0],  uy = from[1],  uz = from[2];
  258.       out[i][0] = ux * m0;
  259.       out[i][1] =           uy * m5;
  260.       out[i][2] =                     uz * m10;
  261.    }
  262.    dest->count = in->count;
  263. }
  264.  
  265.  
  266. static void _XFORMAPI
  267. TAG(transform_normals)( const GLmatrix *mat,
  268.                         GLfloat scale,
  269.                         const GLvector4f *in,
  270.                         const GLfloat *lengths,
  271.                         GLvector4f *dest )
  272. {
  273.    GLfloat (*out)[4] = (GLfloat (*)[4])dest->start;
  274.    const GLfloat *from = in->start;
  275.    const GLuint stride = in->stride;
  276.    const GLuint count = in->count;
  277.    const GLfloat *m = mat->inv;
  278.    const GLfloat m0 = m[0],  m4 = m[4],  m8 = m[8];
  279.    const GLfloat m1 = m[1],  m5 = m[5],  m9 = m[9];
  280.    const GLfloat m2 = m[2],  m6 = m[6],  m10 = m[10];
  281.    GLuint i;
  282.  
  283.    (void) scale;
  284.    (void) lengths;
  285.  
  286.    STRIDE_LOOP {
  287.       GLfloat ux = from[0],  uy = from[1],  uz = from[2];
  288.       out[i][0] = ux * m0 + uy * m1 + uz * m2;
  289.       out[i][1] = ux * m4 + uy * m5 + uz * m6;
  290.       out[i][2] = ux * m8 + uy * m9 + uz * m10;
  291.    }
  292.    dest->count = in->count;
  293. }
  294.  
  295.  
  296. static void _XFORMAPI
  297. TAG(normalize_normals)( const GLmatrix *mat,
  298.                         GLfloat scale,
  299.                         const GLvector4f *in,
  300.                         const GLfloat *lengths,
  301.                         GLvector4f *dest )
  302. {
  303.    GLfloat (*out)[4] = (GLfloat (*)[4])dest->start;
  304.    const GLfloat *from = in->start;
  305.    const GLuint stride = in->stride;
  306.    const GLuint count = in->count;
  307.    GLuint i;
  308.  
  309.    (void) mat;
  310.    (void) scale;
  311.  
  312.    if (lengths) {
  313.       STRIDE_LOOP {
  314.      const GLfloat x = from[0], y = from[1], z = from[2];
  315.      GLfloat invlen = lengths[i];
  316.      out[i][0] = x * invlen;
  317.      out[i][1] = y * invlen;
  318.      out[i][2] = z * invlen;
  319.       }
  320.    }
  321.    else {
  322.       STRIDE_LOOP {
  323.      const GLfloat x = from[0], y = from[1], z = from[2];
  324.      GLdouble len = x * x + y * y + z * z;
  325.      if (len > 1e-50) {
  326.         len = 1.0 / GL_SQRT(len);
  327.         out[i][0] = (GLfloat) (x * len);
  328.         out[i][1] = (GLfloat) (y * len);
  329.         out[i][2] = (GLfloat) (z * len);
  330.      }
  331.      else {
  332.         out[i][0] = x;
  333.         out[i][1] = y;
  334.         out[i][2] = z;
  335.      }
  336.       }
  337.    }
  338.    dest->count = in->count;
  339. }
  340.  
  341.  
  342. static void _XFORMAPI
  343. TAG(rescale_normals)( const GLmatrix *mat,
  344.                       GLfloat scale,
  345.                       const GLvector4f *in,
  346.                       const GLfloat *lengths,
  347.                       GLvector4f *dest )
  348. {
  349.    GLfloat (*out)[4] = (GLfloat (*)[4])dest->start;
  350.    const GLfloat *from = in->start;
  351.    const GLuint stride = in->stride;
  352.    const GLuint count = in->count;
  353.    GLuint i;
  354.  
  355.    (void) mat;
  356.    (void) lengths;
  357.  
  358.    STRIDE_LOOP {
  359.       SCALE_SCALAR_3V( out[i], scale, from );
  360.    }
  361.    dest->count = in->count;
  362. }
  363.  
  364.  
  365. static void _XFORMAPI
  366. TAG(init_c_norm_transform)( void )
  367. {
  368.    _mesa_normal_tab[NORM_TRANSFORM_NO_ROT] =
  369.       TAG(transform_normals_no_rot);
  370.  
  371.    _mesa_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_RESCALE] =
  372.       TAG(transform_rescale_normals_no_rot);
  373.  
  374.    _mesa_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE] =
  375.       TAG(transform_normalize_normals_no_rot);
  376.  
  377.    _mesa_normal_tab[NORM_TRANSFORM] =
  378.       TAG(transform_normals);
  379.  
  380.    _mesa_normal_tab[NORM_TRANSFORM | NORM_RESCALE] =
  381.       TAG(transform_rescale_normals);
  382.  
  383.    _mesa_normal_tab[NORM_TRANSFORM | NORM_NORMALIZE] =
  384.       TAG(transform_normalize_normals);
  385.  
  386.    _mesa_normal_tab[NORM_RESCALE] =
  387.       TAG(rescale_normals);
  388.  
  389.    _mesa_normal_tab[NORM_NORMALIZE] =
  390.       TAG(normalize_normals);
  391. }
  392.