123caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 223caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell/* 323caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell * Mesa 3-D graphics library 422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 527558a160a9fe91745728d7626995cd88f8fe339Brian Paul * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. 622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 723caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a 823caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell * copy of this software and associated documentation files (the "Software"), 923caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell * to deal in the Software without restriction, including without limitation 1023caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1123caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell * and/or sell copies of the Software, and to permit persons to whom the 1223caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell * Software is furnished to do so, subject to the following conditions: 1322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 1423caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell * The above copyright notice and this permission notice shall be included 1523caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell * in all copies or substantial portions of the Software. 1622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 1723caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1823caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1923caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 203d8d5b298a268b119d840bc9bae0ee9e0c9244a9Kenneth Graunke * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 213d8d5b298a268b119d840bc9bae0ee9e0c9244a9Kenneth Graunke * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 223d8d5b298a268b119d840bc9bae0ee9e0c9244a9Kenneth Graunke * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 233d8d5b298a268b119d840bc9bae0ee9e0c9244a9Kenneth Graunke * OTHER DEALINGS IN THE SOFTWARE. 2423caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell */ 2523caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 2623caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell/* 2723caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell * New (3.1) transformation code written by Keith Whitwell. 2823caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell */ 2923caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 30ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul/* Functions to tranform a vector of normals. This includes applying 31ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul * the transformation matrix, rescaling and normalization. 32ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul */ 33ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul 34ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul/* 35ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul * mat - the 4x4 transformation matrix 36ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul * scale - uniform scale factor of the transformation matrix (not always used) 37ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul * in - the source vector of normals 38ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul * lengths - length of each incoming normal (may be NULL) (a display list 39ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul * optimization) 40ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul * dest - the destination vector of normals 41ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul */ 4209ffa04cd9c560b7a8c6d8ac80e3d59c49c5ef70Brian Paulstatic void 4323caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith WhitwellTAG(transform_normalize_normals)( const GLmatrix *mat, 4423caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell GLfloat scale, 45bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul const GLvector4f *in, 4623caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell const GLfloat *lengths, 47bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul GLvector4f *dest ) 4823caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell{ 49bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul GLfloat (*out)[4] = (GLfloat (*)[4])dest->start; 50ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLfloat *from = in->start; 51ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLuint stride = in->stride; 52ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLuint count = in->count; 53ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLfloat *m = mat->inv; 5423caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell GLfloat m0 = m[0], m4 = m[4], m8 = m[8]; 5523caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell GLfloat m1 = m[1], m5 = m[5], m9 = m[9]; 5623caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell GLfloat m2 = m[2], m6 = m[6], m10 = m[10]; 57ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul GLuint i; 5823caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 5923caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell if (!lengths) { 6023caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell STRIDE_LOOP { 615e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes GLfloat tx, ty, tz; 625e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes { 635e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes const GLfloat ux = from[0], uy = from[1], uz = from[2]; 645e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes tx = ux * m0 + uy * m1 + uz * m2; 655e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes ty = ux * m4 + uy * m5 + uz * m6; 665e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes tz = ux * m8 + uy * m9 + uz * m10; 675e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes } 685e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes { 695e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes GLdouble len = tx*tx + ty*ty + tz*tz; 705e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes if (len > 1e-20) { 71a2b366b92cecc5045293528aa0bb8b1f0678bbccBrian Paul GLfloat scale = 1.0f / sqrtf(len); 72f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul out[i][0] = tx * scale; 73f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul out[i][1] = ty * scale; 74f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul out[i][2] = tz * scale; 7523caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 76ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul else { 775e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][0] = out[i][1] = out[i][2] = 0; 7823caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 7923caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 8023caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 8123caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 8223caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell else { 837adc9fa1f1d12683c5855bf5854dec814629093dMatt Turner if (scale != 1.0f) { 8423caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell m0 *= scale, m4 *= scale, m8 *= scale; 8523caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell m1 *= scale, m5 *= scale, m9 *= scale; 8623caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell m2 *= scale, m6 *= scale, m10 *= scale; 8723caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 8823caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 8923caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell STRIDE_LOOP { 905e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes GLfloat tx, ty, tz; 915e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes { 925e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes const GLfloat ux = from[0], uy = from[1], uz = from[2]; 935e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes tx = ux * m0 + uy * m1 + uz * m2; 945e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes ty = ux * m4 + uy * m5 + uz * m6; 955e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes tz = ux * m8 + uy * m9 + uz * m10; 965e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes } 975e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes { 985e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes GLfloat len = lengths[i]; 995e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][0] = tx * len; 1005e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][1] = ty * len; 1015e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][2] = tz * len; 10223caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 10323caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 10423caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 10523caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell dest->count = in->count; 10623caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell} 10723caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 10823caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 10909ffa04cd9c560b7a8c6d8ac80e3d59c49c5ef70Brian Paulstatic void 11023caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith WhitwellTAG(transform_normalize_normals_no_rot)( const GLmatrix *mat, 11123caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell GLfloat scale, 112bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul const GLvector4f *in, 11323caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell const GLfloat *lengths, 114bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul GLvector4f *dest ) 11523caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell{ 116bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul GLfloat (*out)[4] = (GLfloat (*)[4])dest->start; 117ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLfloat *from = in->start; 118ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLuint stride = in->stride; 119ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLuint count = in->count; 120ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLfloat *m = mat->inv; 12123caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell GLfloat m0 = m[0]; 12223caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell GLfloat m5 = m[5]; 12323caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell GLfloat m10 = m[10]; 124ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul GLuint i; 125ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul 12623caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell if (!lengths) { 12723caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell STRIDE_LOOP { 1285e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes GLfloat tx, ty, tz; 1295e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes { 1305e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes const GLfloat ux = from[0], uy = from[1], uz = from[2]; 1315e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes tx = ux * m0 ; 1325e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes ty = uy * m5 ; 1335e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes tz = uz * m10; 1345e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes } 1355e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes { 1365e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes GLdouble len = tx*tx + ty*ty + tz*tz; 1375e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes if (len > 1e-20) { 138a2b366b92cecc5045293528aa0bb8b1f0678bbccBrian Paul GLfloat scale = 1.0f / sqrtf(len); 139f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul out[i][0] = tx * scale; 140f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul out[i][1] = ty * scale; 141f9b1e5241facc8cf255c258082d5cb5b04783e93Brian Paul out[i][2] = tz * scale; 14223caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 143ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul else { 1445e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][0] = out[i][1] = out[i][2] = 0; 14523caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 14623caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 14723caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 14823caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 14923caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell else { 15047a28c0b4d4ca27592e3cbb8e4b17d1cd8f7997dKeith Whitwell m0 *= scale; 15147a28c0b4d4ca27592e3cbb8e4b17d1cd8f7997dKeith Whitwell m5 *= scale; 15247a28c0b4d4ca27592e3cbb8e4b17d1cd8f7997dKeith Whitwell m10 *= scale; 15323caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 15423caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell STRIDE_LOOP { 1555e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes GLfloat tx, ty, tz; 1565e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes { 1575e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes const GLfloat ux = from[0], uy = from[1], uz = from[2]; 1585e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes tx = ux * m0 ; 1595e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes ty = uy * m5 ; 1605e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes tz = uz * m10; 1615e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes } 1625e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes { 1635e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes GLfloat len = lengths[i]; 1645e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][0] = tx * len; 1655e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][1] = ty * len; 1665e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][2] = tz * len; 16723caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 16823caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 16923caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 17023caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell dest->count = in->count; 17123caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell} 17223caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 17323caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 17409ffa04cd9c560b7a8c6d8ac80e3d59c49c5ef70Brian Paulstatic void 17523caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith WhitwellTAG(transform_rescale_normals_no_rot)( const GLmatrix *mat, 17623caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell GLfloat scale, 177bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul const GLvector4f *in, 17823caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell const GLfloat *lengths, 179bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul GLvector4f *dest ) 18023caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell{ 181bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul GLfloat (*out)[4] = (GLfloat (*)[4])dest->start; 182ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLfloat *from = in->start; 183ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLuint stride = in->stride; 184ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLuint count = in->count; 18523caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell const GLfloat *m = mat->inv; 186ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLfloat m0 = scale*m[0]; 187ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLfloat m5 = scale*m[5]; 188ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLfloat m10 = scale*m[10]; 189ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul GLuint i; 190ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul 19123caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell (void) lengths; 192ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul 19323caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell STRIDE_LOOP { 1945e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes GLfloat ux = from[0], uy = from[1], uz = from[2]; 1955e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][0] = ux * m0; 1965e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][1] = uy * m5; 1975e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][2] = uz * m10; 19823caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 19923caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell dest->count = in->count; 20023caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell} 20123caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 202ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul 20309ffa04cd9c560b7a8c6d8ac80e3d59c49c5ef70Brian Paulstatic void 20423caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith WhitwellTAG(transform_rescale_normals)( const GLmatrix *mat, 20523caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell GLfloat scale, 206bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul const GLvector4f *in, 20723caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell const GLfloat *lengths, 208bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul GLvector4f *dest ) 20923caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell{ 210bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul GLfloat (*out)[4] = (GLfloat (*)[4])dest->start; 211ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLfloat *from = in->start; 212ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLuint stride = in->stride; 213ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLuint count = in->count; 21423caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell /* Since we are unlikely to have < 3 vertices in the buffer, 21523caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell * it makes sense to pre-multiply by scale. 21623caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell */ 21723caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell const GLfloat *m = mat->inv; 218ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLfloat m0 = scale*m[0], m4 = scale*m[4], m8 = scale*m[8]; 219ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLfloat m1 = scale*m[1], m5 = scale*m[5], m9 = scale*m[9]; 220ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLfloat m2 = scale*m[2], m6 = scale*m[6], m10 = scale*m[10]; 221ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul GLuint i; 222ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul 22323caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell (void) lengths; 224ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul 22523caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell STRIDE_LOOP { 2265e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes GLfloat ux = from[0], uy = from[1], uz = from[2]; 2275e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][0] = ux * m0 + uy * m1 + uz * m2; 2285e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][1] = ux * m4 + uy * m5 + uz * m6; 2295e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][2] = ux * m8 + uy * m9 + uz * m10; 23023caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 23123caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell dest->count = in->count; 23223caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell} 23323caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 23423caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 23509ffa04cd9c560b7a8c6d8ac80e3d59c49c5ef70Brian Paulstatic void 23679b2d13ae2280650070d5a0f157afecbfa02f9e6Gareth HughesTAG(transform_normals_no_rot)( const GLmatrix *mat, 23779b2d13ae2280650070d5a0f157afecbfa02f9e6Gareth Hughes GLfloat scale, 238bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul const GLvector4f *in, 23979b2d13ae2280650070d5a0f157afecbfa02f9e6Gareth Hughes const GLfloat *lengths, 240bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul GLvector4f *dest ) 24123caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell{ 242bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul GLfloat (*out)[4] = (GLfloat (*)[4])dest->start; 243ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLfloat *from = in->start; 244ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLuint stride = in->stride; 245ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLuint count = in->count; 24623caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell const GLfloat *m = mat->inv; 247ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLfloat m0 = m[0]; 248ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLfloat m5 = m[5]; 249ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLfloat m10 = m[10]; 250ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul GLuint i; 251ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul 25223caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell (void) scale; 25323caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell (void) lengths; 254ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul 25523caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell STRIDE_LOOP { 2565e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes GLfloat ux = from[0], uy = from[1], uz = from[2]; 2575e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][0] = ux * m0; 2585e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][1] = uy * m5; 2595e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][2] = uz * m10; 26023caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 26123caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell dest->count = in->count; 26223caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell} 26323caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 26423caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 26509ffa04cd9c560b7a8c6d8ac80e3d59c49c5ef70Brian Paulstatic void 26623caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith WhitwellTAG(transform_normals)( const GLmatrix *mat, 26723caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell GLfloat scale, 268bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul const GLvector4f *in, 26923caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell const GLfloat *lengths, 270bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul GLvector4f *dest ) 27123caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell{ 272bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul GLfloat (*out)[4] = (GLfloat (*)[4])dest->start; 273ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLfloat *from = in->start; 274ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLuint stride = in->stride; 275ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLuint count = in->count; 27623caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell const GLfloat *m = mat->inv; 277ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLfloat m0 = m[0], m4 = m[4], m8 = m[8]; 278ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLfloat m1 = m[1], m5 = m[5], m9 = m[9]; 279ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLfloat m2 = m[2], m6 = m[6], m10 = m[10]; 280ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul GLuint i; 281ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul 28223caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell (void) scale; 28323caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell (void) lengths; 284ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul 28523caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell STRIDE_LOOP { 2865e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes GLfloat ux = from[0], uy = from[1], uz = from[2]; 2875e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][0] = ux * m0 + uy * m1 + uz * m2; 2885e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][1] = ux * m4 + uy * m5 + uz * m6; 2895e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][2] = ux * m8 + uy * m9 + uz * m10; 29023caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 29123caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell dest->count = in->count; 29223caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell} 29323caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 29423caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 29509ffa04cd9c560b7a8c6d8ac80e3d59c49c5ef70Brian Paulstatic void 29623caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith WhitwellTAG(normalize_normals)( const GLmatrix *mat, 29723caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell GLfloat scale, 298bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul const GLvector4f *in, 29923caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell const GLfloat *lengths, 300bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul GLvector4f *dest ) 30123caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell{ 302bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul GLfloat (*out)[4] = (GLfloat (*)[4])dest->start; 303ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLfloat *from = in->start; 304ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLuint stride = in->stride; 305ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLuint count = in->count; 306ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul GLuint i; 307ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul 30823caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell (void) mat; 30923caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell (void) scale; 310ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul 31123caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell if (lengths) { 31223caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell STRIDE_LOOP { 3135e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes const GLfloat x = from[0], y = from[1], z = from[2]; 3145e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes GLfloat invlen = lengths[i]; 3155e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][0] = x * invlen; 3165e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][1] = y * invlen; 3175e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][2] = z * invlen; 31823caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 31923caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 32023caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell else { 32123caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell STRIDE_LOOP { 3225e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes const GLfloat x = from[0], y = from[1], z = from[2]; 3235e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes GLdouble len = x * x + y * y + z * z; 3245e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes if (len > 1e-50) { 325a2b366b92cecc5045293528aa0bb8b1f0678bbccBrian Paul len = 1.0f / sqrtf(len); 326dc24230de7f913969b52dee3579bb8fa3d50a8c0Karl Schultz out[i][0] = (GLfloat)(x * len); 327dc24230de7f913969b52dee3579bb8fa3d50a8c0Karl Schultz out[i][1] = (GLfloat)(y * len); 328dc24230de7f913969b52dee3579bb8fa3d50a8c0Karl Schultz out[i][2] = (GLfloat)(z * len); 3295e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes } 3305e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes else { 3315e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][0] = x; 3325e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][1] = y; 3335e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes out[i][2] = z; 33422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes } 33523caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 33623caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 33723caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell dest->count = in->count; 33823caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell} 33923caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 34023caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 34109ffa04cd9c560b7a8c6d8ac80e3d59c49c5ef70Brian Paulstatic void 34223caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith WhitwellTAG(rescale_normals)( const GLmatrix *mat, 34323caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell GLfloat scale, 344bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul const GLvector4f *in, 34523caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell const GLfloat *lengths, 346bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul GLvector4f *dest ) 34723caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell{ 348bd1a9dacf6a45e6aa6954eeb490d55ebcc80ace8Brian Paul GLfloat (*out)[4] = (GLfloat (*)[4])dest->start; 349ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLfloat *from = in->start; 350ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLuint stride = in->stride; 351ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul const GLuint count = in->count; 352ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul GLuint i; 353ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul 35423caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell (void) mat; 35523caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell (void) lengths; 356ca209ae1f95760bef87a10bca031bdbd6fb3ac3cBrian Paul 35723caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell STRIDE_LOOP { 3585e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes SCALE_SCALAR_3V( out[i], scale, from ); 35923caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell } 36023caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell dest->count = in->count; 36123caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell} 36223caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 36323caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 36409ffa04cd9c560b7a8c6d8ac80e3d59c49c5ef70Brian Paulstatic void 36523caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith WhitwellTAG(init_c_norm_transform)( void ) 36623caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell{ 3675e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes _mesa_normal_tab[NORM_TRANSFORM_NO_ROT] = 36823caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell TAG(transform_normals_no_rot); 36923caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 3705e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes _mesa_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_RESCALE] = 37123caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell TAG(transform_rescale_normals_no_rot); 37223caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 3735e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes _mesa_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE] = 37423caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell TAG(transform_normalize_normals_no_rot); 37523caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 3765e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes _mesa_normal_tab[NORM_TRANSFORM] = 37723caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell TAG(transform_normals); 37823caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 3795e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes _mesa_normal_tab[NORM_TRANSFORM | NORM_RESCALE] = 38023caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell TAG(transform_rescale_normals); 38123caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 3825e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes _mesa_normal_tab[NORM_TRANSFORM | NORM_NORMALIZE] = 38323caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell TAG(transform_normalize_normals); 38423caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 3855e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes _mesa_normal_tab[NORM_RESCALE] = 38623caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell TAG(rescale_normals); 38723caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell 3885e23af22f708a66695c0e44e599c26f02d8d4dcdGareth Hughes _mesa_normal_tab[NORM_NORMALIZE] = 38923caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell TAG(normalize_normals); 39023caf20169ac38436ee9c13914f1d6aa7cf6bb5eKeith Whitwell} 391