Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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