OSDN Git Service

24839e2b5cdc9c1572fee77431face231351a544
[android-x86/external-mesa.git] / src / mesa / math / m_norm_tmp.h
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  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24  * 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                GLfloat scale = INV_SQRTF(len);
73                out[i][0] = tx * scale;
74                out[i][1] = ty * scale;
75                out[i][2] = 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                GLfloat scale = INV_SQRTF(len);
140                out[i][0] = tx * scale;
141                out[i][1] = ty * scale;
142                out[i][2] = 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 = INV_SQRTF(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 }