home *** CD-ROM | disk | FTP | other *** search
/ Amiga Magazin: Amiga-CD 2000 April & May / AMIGA_2000_04.iso / patches / mesa3.1 / mesa-3_1.lha / src / norm_tmp.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-07  |  10.5 KB  |  403 lines

  1. /* $Id: norm_tmp.h,v 1.2 1999/11/05 06:43:10 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.1
  6.  * 
  7.  * Copyright (C) 1999  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.  
  32. static void TAG(transform_normalize_normals)( const GLmatrix *mat,
  33.                           GLfloat scale,
  34.                           const GLvector3f *in,
  35.                           const GLfloat *lengths,
  36.                           const GLubyte mask[],
  37.                           GLvector3f *dest )
  38. {
  39.    GLuint i;  
  40.    const GLfloat *from = in->start;
  41.    GLuint stride = in->stride;
  42.    GLuint count = in->count;
  43.    GLfloat (*out)[3] = (GLfloat (*)[3])dest->start;
  44.    GLfloat *m = mat->inv;
  45.    GLfloat m0 = m[0],  m4 = m[4],  m8 = m[8];
  46.    GLfloat m1 = m[1],  m5 = m[5],  m9 = m[9];
  47.    GLfloat m2 = m[2],  m6 = m[6],  m10 = m[10];
  48.  
  49.    (void) mask;
  50.    if (!lengths) {
  51.       STRIDE_LOOP {
  52.      CULL_CHECK {
  53.         GLfloat tx, ty, tz;
  54.         {
  55.            const GLfloat ux = from[0],  uy = from[1],  uz = from[2];
  56.            tx = ux * m0 + uy * m1 + uz * m2;
  57.            ty = ux * m4 + uy * m5 + uz * m6;
  58.            tz = ux * m8 + uy * m9 + uz * m10;
  59.         }
  60.         {
  61.            GLdouble len = tx*tx + ty*ty + tz*tz;
  62.            if (len > 1e-20) {
  63.           GLdouble scale = 1.0 / GL_SQRT(len);
  64.           out[i][0] = (GLfloat) (tx * scale);
  65.           out[i][1] = (GLfloat) (ty * scale);
  66.           out[i][2] = (GLfloat) (tz * scale);
  67.            }
  68.            else
  69.            {
  70.           out[i][0] = out[i][1] = out[i][2] = 0;
  71.            }
  72.         }
  73.      }
  74.       }
  75.    } else {
  76.       
  77.       /* scale has been snapped to 1.0 if it is close.
  78.        */
  79.       if (scale != 1.0) {
  80.      m0 *= scale,  m4 *= scale,  m8 *= scale;
  81.      m1 *= scale,  m5 *= scale,  m9 *= scale;
  82.      m2 *= scale,  m6 *= scale,  m10 *= scale;
  83.       }
  84.  
  85.       STRIDE_LOOP {
  86.      CULL_CHECK {
  87.         GLfloat tx, ty, tz;
  88.         {
  89.            const GLfloat ux = from[0],  uy = from[1],  uz = from[2];
  90.            tx = ux * m0 + uy * m1 + uz * m2;
  91.            ty = ux * m4 + uy * m5 + uz * m6;
  92.            tz = ux * m8 + uy * m9 + uz * m10;
  93.         }
  94.         {
  95.            GLfloat len = lengths[i];
  96.            out[i][0] = tx * len;
  97.            out[i][1] = ty * len;
  98.            out[i][2] = tz * len;
  99.         }
  100.      }
  101.       }
  102.    }
  103.    dest->count = in->count;
  104. }
  105.  
  106. static void TAG(transform_normalize_normals_no_rot)( const GLmatrix *mat,
  107.                              GLfloat scale,
  108.                              const GLvector3f *in,
  109.                              const GLfloat *lengths,
  110.                              const GLubyte mask[],
  111.                              GLvector3f *dest )
  112. {
  113.    GLuint i;  
  114.    const GLfloat *from = in->start;
  115.    GLuint stride = in->stride;
  116.    GLuint count = in->count;
  117.    GLfloat (*out)[3] = (GLfloat (*)[3])dest->start;
  118.    GLfloat *m = mat->inv;
  119.    GLfloat m0 = m[0];
  120.    GLfloat m5 = m[5];
  121.    GLfloat m10 = m[10];
  122.    (void) mask;
  123.    if (!lengths) {
  124.       STRIDE_LOOP {
  125.      CULL_CHECK {
  126.         GLfloat tx, ty, tz;
  127.         {
  128.            const GLfloat ux = from[0],  uy = from[1],  uz = from[2];
  129.            tx = ux * m0                    ;
  130.            ty =           uy * m5          ;
  131.            tz =                     uz * m10;
  132.         }
  133.         {
  134.            GLdouble len = tx*tx + ty*ty + tz*tz;
  135.            if (len > 1e-20) {
  136.           GLdouble scale = 1.0 / GL_SQRT(len);
  137.           out[i][0] = (GLfloat) (tx * scale);
  138.           out[i][1] = (GLfloat) (ty * scale);
  139.           out[i][2] = (GLfloat) (tz * scale);
  140.            }
  141.            else
  142.            {
  143.           out[i][0] = out[i][1] = out[i][2] = 0;
  144.            }
  145.         }
  146.      }
  147.       }
  148.    } else {
  149.       /* scale has been snapped to 1.0 if it is close.
  150.        */
  151.       if (scale != 1.0) {
  152.      m0 *= scale; 
  153.      m5 *= scale;
  154.      m10 *= scale;
  155.       }
  156.  
  157.       STRIDE_LOOP {
  158.      CULL_CHECK {
  159.         GLfloat tx, ty, tz;
  160.         {
  161.            const GLfloat ux = from[0],  uy = from[1],  uz = from[2];
  162.            tx = ux * m0                    ;
  163.            ty =           uy * m5          ;
  164.            tz =                     uz * m10;
  165.         }
  166.         {
  167.            GLfloat len = lengths[i];
  168.            out[i][0] = tx * len;
  169.            out[i][1] = ty * len;
  170.            out[i][2] = tz * len;
  171.         }
  172.      }
  173.       }
  174.    }
  175.    dest->count = in->count;
  176. }
  177.  
  178.  
  179. static void TAG(transform_rescale_normals_no_rot)( const GLmatrix *mat,
  180.                            GLfloat scale,
  181.                            const GLvector3f *in,
  182.                            const GLfloat *lengths,
  183.                            const GLubyte mask[],
  184.                            GLvector3f *dest )
  185. {
  186.    GLuint i;  
  187.    const GLfloat *from = in->start;
  188.    GLuint stride = in->stride;
  189.    GLuint count = in->count;
  190.    GLfloat (*out)[3] = (GLfloat (*)[3])dest->start;
  191.    const GLfloat *m = mat->inv;
  192.    GLfloat m0 = scale*m[0];
  193.    GLfloat m5 = scale*m[5];
  194.    GLfloat m10 = scale*m[10];
  195.    (void) lengths;
  196.    (void) mask;
  197.    STRIDE_LOOP {
  198.       CULL_CHECK {
  199.      GLfloat ux = from[0],  uy = from[1],  uz = from[2];
  200.      out[i][0] = ux * m0;
  201.      out[i][1] =           uy * m5;
  202.      out[i][2] =                     uz * m10;
  203.       }
  204.    }
  205.    dest->count = in->count;
  206. }
  207.  
  208. static void TAG(transform_rescale_normals)( const GLmatrix *mat,
  209.                         GLfloat scale,
  210.                         const GLvector3f *in,
  211.                         const GLfloat *lengths,
  212.                         const GLubyte mask[],
  213.                         GLvector3f *dest )
  214. {
  215.    GLuint i;  
  216.    const GLfloat *from = in->start;
  217.    GLuint stride = in->stride;
  218.    GLuint count = in->count;
  219.    GLfloat (*out)[3] = (GLfloat (*)[3])dest->start;
  220.    /* Since we are unlikely to have < 3 vertices in the buffer,
  221.     * it makes sense to pre-multiply by scale.
  222.     */
  223.    const GLfloat *m = mat->inv;
  224.    GLfloat m0 = scale*m[0],  m4 = scale*m[4],  m8 = scale*m[8];
  225.    GLfloat m1 = scale*m[1],  m5 = scale*m[5],  m9 = scale*m[9];
  226.    GLfloat m2 = scale*m[2],  m6 = scale*m[6],  m10 = scale*m[10];
  227.    (void) lengths;
  228.    (void) mask;
  229.    STRIDE_LOOP {
  230.       CULL_CHECK {
  231.      GLfloat ux = from[0],  uy = from[1],  uz = from[2];
  232.      out[i][0] = ux * m0 + uy * m1 + uz * m2;
  233.      out[i][1] = ux * m4 + uy * m5 + uz * m6;
  234.      out[i][2] = ux * m8 + uy * m9 + uz * m10;
  235.       }
  236.    }
  237.    dest->count = in->count;
  238. }
  239.  
  240.  
  241. static void TAG(transform_normals_no_rot)(const GLmatrix *mat,
  242.                       GLfloat scale,
  243.                       const GLvector3f *in,
  244.                       const GLfloat *lengths,
  245.                       const GLubyte mask[],
  246.                       GLvector3f *dest )
  247. {
  248.    GLuint i;  
  249.    const GLfloat *from = in->start;
  250.    GLuint stride = in->stride;
  251.    GLuint count = in->count;
  252.    GLfloat (*out)[3] = (GLfloat (*)[3])dest->start;
  253.    const GLfloat *m = mat->inv;
  254.    GLfloat m0 = m[0];
  255.    GLfloat m5 = m[5];
  256.    GLfloat m10 = m[10];
  257.    (void) scale;
  258.    (void) lengths;
  259.    (void) mask;
  260.    STRIDE_LOOP {
  261.       CULL_CHECK {
  262.      GLfloat ux = from[0],  uy = from[1],  uz = from[2];
  263.      out[i][0] = ux * m0;
  264.      out[i][1] =           uy * m5;
  265.      out[i][2] =                     uz * m10;
  266.       }
  267.    }
  268.    dest->count = in->count;
  269. }
  270.  
  271. static void TAG(transform_normals)( const GLmatrix *mat,
  272.                     GLfloat scale,
  273.                     const GLvector3f *in,
  274.                     const GLfloat *lengths,
  275.                     const GLubyte mask[],
  276.                     GLvector3f *dest )
  277. {
  278.    GLuint i;  
  279.    const GLfloat *from = in->start;
  280.    GLuint stride = in->stride;
  281.    GLuint count = in->count;
  282.    GLfloat (*out)[3] = (GLfloat (*)[3])dest->start;
  283.    const GLfloat *m = mat->inv;
  284.    GLfloat m0 = m[0],  m4 = m[4],  m8 = m[8];
  285.    GLfloat m1 = m[1],  m5 = m[5],  m9 = m[9];
  286.    GLfloat m2 = m[2],  m6 = m[6],  m10 = m[10];
  287.    (void) scale;
  288.    (void) lengths;
  289.    (void) mask;
  290.    STRIDE_LOOP {
  291.       CULL_CHECK {
  292.      GLfloat ux = from[0],  uy = from[1],  uz = from[2];
  293.      out[i][0] = ux * m0 + uy * m1 + uz * m2;
  294.      out[i][1] = ux * m4 + uy * m5 + uz * m6;
  295.      out[i][2] = ux * m8 + uy * m9 + uz * m10;
  296.       }
  297.    }
  298.    dest->count = in->count;
  299. }
  300.  
  301.  
  302. static void TAG(normalize_normals)( const GLmatrix *mat,
  303.                     GLfloat scale,
  304.                     const GLvector3f *in,
  305.                     const GLfloat *lengths,
  306.                     const GLubyte mask[],
  307.                     GLvector3f *dest )
  308. {
  309.    GLuint i;  
  310.    const GLfloat *from = in->start;
  311.    GLuint stride = in->stride;
  312.    GLuint count = in->count;
  313.    GLfloat (*out)[3] = (GLfloat (*)[3])dest->start;
  314.    (void) mat;
  315.    (void) mask;
  316.    (void) scale;
  317.    if (lengths) {
  318.       STRIDE_LOOP {
  319.      CULL_CHECK {
  320.         const GLfloat x = from[0], y = from[1], z = from[2];
  321.         GLfloat invlen = lengths[i];
  322.         out[i][0] = x * invlen;
  323.         out[i][1] = y * invlen;
  324.         out[i][2] = z * invlen;
  325.      }     
  326.       }
  327.    }
  328.    else {
  329.       STRIDE_LOOP {
  330.      CULL_CHECK {
  331.         const GLfloat x = from[0], y = from[1], z = from[2];
  332.         GLdouble len = x * x + y * y + z * z;
  333.         if (len > 1e-50) {
  334.            len = 1.0 / GL_SQRT(len);
  335.            out[i][0] = (GLfloat) (x * len);
  336.            out[i][1] = (GLfloat) (y * len);
  337.            out[i][2] = (GLfloat) (z * len);
  338.         }
  339.         else {
  340.            out[i][0] = x;
  341.            out[i][1] = y;
  342.            out[i][2] = z;
  343.         }
  344.      }     
  345.       }
  346.    }
  347.    dest->count = in->count;
  348. }
  349.  
  350.  
  351. static void TAG(rescale_normals)( const GLmatrix *mat,
  352.                   GLfloat scale,
  353.                   const GLvector3f *in,
  354.                   const GLfloat *lengths,
  355.                   const GLubyte mask[],
  356.                   GLvector3f *dest )
  357. {
  358.    GLuint i;  
  359.    const GLfloat *from = in->start;
  360.    GLuint stride = in->stride;
  361.    GLuint count = in->count;
  362.    GLfloat (*out)[3] = (GLfloat (*)[3])dest->start;
  363.    (void) mat;
  364.    (void) lengths;
  365.    (void) mask;
  366.  
  367.    STRIDE_LOOP {
  368.       CULL_CHECK {
  369.      SCALE_SCALAR_3V( out[i], scale, from );
  370.       }
  371.    }
  372.    dest->count = in->count;
  373. }
  374.  
  375.  
  376. static void TAG(init_c_norm_transform)( void )
  377. {
  378.    gl_normal_tab[NORM_TRANSFORM_NO_ROT][IDX] = 
  379.       TAG(transform_normals_no_rot);
  380.  
  381.    gl_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_RESCALE][IDX] = 
  382.       TAG(transform_rescale_normals_no_rot);
  383.  
  384.    gl_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE][IDX] = 
  385.       TAG(transform_normalize_normals_no_rot);
  386.  
  387.    gl_normal_tab[NORM_TRANSFORM][IDX] = 
  388.       TAG(transform_normals);
  389.  
  390.    gl_normal_tab[NORM_TRANSFORM | NORM_RESCALE][IDX] = 
  391.       TAG(transform_rescale_normals);
  392.  
  393.    gl_normal_tab[NORM_TRANSFORM | NORM_NORMALIZE][IDX] = 
  394.       TAG(transform_normalize_normals);
  395.  
  396.    gl_normal_tab[NORM_RESCALE][IDX] = 
  397.       TAG(rescale_normals);
  398.  
  399.    gl_normal_tab[NORM_NORMALIZE][IDX] = 
  400.       TAG(normalize_normals);
  401.  
  402. }
  403.