source: trunk/src/opengl/mesa/norm_tmp.h

Last change on this file was 3597, checked in by jeroen, 25 years ago

* empty log message *

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