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