Killed mmath.[ch]. Moved low-level functions/assembly code into imports.[ch]
[mesa.git] / src / mesa / math / m_norm_tmp.h
1 /* $Id: m_norm_tmp.h,v 1.13 2003/03/01 01:50:24 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 5.1
6 *
7 * Copyright (C) 1999-2003 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.0F / SQRTF(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.0F / SQRTF(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.0F / 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 }