Subversion Repositories shark

Rev

Rev 56 | Details | Compare with Previous | Last modification | View Log | RSS feed

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