~ubuntu-branches/ubuntu/quantal/mesa-glw/quantal

« back to all changes in this revision

Viewing changes to src/mesa/math/m_norm_tmp.h

  • Committer: Bazaar Package Importer
  • Author(s): Morten Kjeldgaard
  • Date: 2008-05-06 16:19:15 UTC
  • Revision ID: james.westby@ubuntu.com-20080506161915-uynz7nftmfixu6bq
Tags: upstream-7.0.3
ImportĀ upstreamĀ versionĀ 7.0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/*
 
3
 * Mesa 3-D graphics library
 
4
 * Version:  5.1
 
5
 *
 
6
 * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
 
7
 *
 
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:
 
14
 *
 
15
 * The above copyright notice and this permission notice shall be included
 
16
 * in all copies or substantial portions of the Software.
 
17
 *
 
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.
 
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 _XFORMAPI
 
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 = INV_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 _XFORMAPI
 
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 = INV_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 _XFORMAPI
 
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 _XFORMAPI
 
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 _XFORMAPI
 
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 _XFORMAPI
 
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 _XFORMAPI
 
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 = INV_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 _XFORMAPI
 
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 _XFORMAPI
 
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
}