3
* Mesa 3-D graphics library
6
* Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
8
* Permission is hereby granted, free of charge, to any person obtaining a
9
* copy of this software and associated documentation files (the "Software"),
10
* to deal in the Software without restriction, including without limitation
11
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
12
* and/or sell copies of the Software, and to permit persons to whom the
13
* Software is furnished to do so, subject to the following conditions:
15
* The above copyright notice and this permission notice shall be included
16
* in all copies or substantial portions of the Software.
18
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
* New (3.1) transformation code written by Keith Whitwell.
30
/* Functions to tranform a vector of normals. This includes applying
31
* the transformation matrix, rescaling and normalization.
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
40
* dest - the destination vector of normals
43
TAG(transform_normalize_normals)( const GLmatrix *mat,
46
const GLfloat *lengths,
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];
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;
69
GLdouble len = tx*tx + ty*ty + tz*tz;
71
GLfloat scale = INV_SQRTF(len);
72
out[i][0] = tx * scale;
73
out[i][1] = ty * scale;
74
out[i][2] = tz * scale;
77
out[i][0] = out[i][1] = out[i][2] = 0;
84
m0 *= scale, m4 *= scale, m8 *= scale;
85
m1 *= scale, m5 *= scale, m9 *= scale;
86
m2 *= scale, m6 *= scale, m10 *= scale;
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;
98
GLfloat len = lengths[i];
100
out[i][1] = ty * len;
101
out[i][2] = tz * len;
105
dest->count = in->count;
109
static void _XFORMAPI
110
TAG(transform_normalize_normals_no_rot)( const GLmatrix *mat,
112
const GLvector4f *in,
113
const GLfloat *lengths,
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;
130
const GLfloat ux = from[0], uy = from[1], uz = from[2];
136
GLdouble len = tx*tx + ty*ty + tz*tz;
138
GLfloat scale = INV_SQRTF(len);
139
out[i][0] = tx * scale;
140
out[i][1] = ty * scale;
141
out[i][2] = tz * scale;
144
out[i][0] = out[i][1] = out[i][2] = 0;
157
const GLfloat ux = from[0], uy = from[1], uz = from[2];
163
GLfloat len = lengths[i];
164
out[i][0] = tx * len;
165
out[i][1] = ty * len;
166
out[i][2] = tz * len;
170
dest->count = in->count;
174
static void _XFORMAPI
175
TAG(transform_rescale_normals_no_rot)( const GLmatrix *mat,
177
const GLvector4f *in,
178
const GLfloat *lengths,
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];
194
GLfloat ux = from[0], uy = from[1], uz = from[2];
197
out[i][2] = uz * m10;
199
dest->count = in->count;
203
static void _XFORMAPI
204
TAG(transform_rescale_normals)( const GLmatrix *mat,
206
const GLvector4f *in,
207
const GLfloat *lengths,
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.
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];
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;
231
dest->count = in->count;
235
static void _XFORMAPI
236
TAG(transform_normals_no_rot)( const GLmatrix *mat,
238
const GLvector4f *in,
239
const GLfloat *lengths,
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];
256
GLfloat ux = from[0], uy = from[1], uz = from[2];
259
out[i][2] = uz * m10;
261
dest->count = in->count;
265
static void _XFORMAPI
266
TAG(transform_normals)( const GLmatrix *mat,
268
const GLvector4f *in,
269
const GLfloat *lengths,
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];
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;
291
dest->count = in->count;
295
static void _XFORMAPI
296
TAG(normalize_normals)( const GLmatrix *mat,
298
const GLvector4f *in,
299
const GLfloat *lengths,
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;
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;
322
const GLfloat x = from[0], y = from[1], z = from[2];
323
GLdouble len = x * x + y * y + z * z;
325
len = INV_SQRTF(len);
326
out[i][0] = (GLfloat)(x * len);
327
out[i][1] = (GLfloat)(y * len);
328
out[i][2] = (GLfloat)(z * len);
337
dest->count = in->count;
341
static void _XFORMAPI
342
TAG(rescale_normals)( const GLmatrix *mat,
344
const GLvector4f *in,
345
const GLfloat *lengths,
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;
358
SCALE_SCALAR_3V( out[i], scale, from );
360
dest->count = in->count;
364
static void _XFORMAPI
365
TAG(init_c_norm_transform)( void )
367
_mesa_normal_tab[NORM_TRANSFORM_NO_ROT] =
368
TAG(transform_normals_no_rot);
370
_mesa_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_RESCALE] =
371
TAG(transform_rescale_normals_no_rot);
373
_mesa_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE] =
374
TAG(transform_normalize_normals_no_rot);
376
_mesa_normal_tab[NORM_TRANSFORM] =
377
TAG(transform_normals);
379
_mesa_normal_tab[NORM_TRANSFORM | NORM_RESCALE] =
380
TAG(transform_rescale_normals);
382
_mesa_normal_tab[NORM_TRANSFORM | NORM_NORMALIZE] =
383
TAG(transform_normalize_normals);
385
_mesa_normal_tab[NORM_RESCALE] =
386
TAG(rescale_normals);
388
_mesa_normal_tab[NORM_NORMALIZE] =
389
TAG(normalize_normals);