1 /* $Id: m_norm_tmp.h,v 1.11 2002/04/09 14:58:04 keithw Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
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:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
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.
28 * New (3.1) transformation code written by Keith Whitwell.
31 /* Functions to tranform a vector of normals. This includes applying
32 * the transformation matrix, rescaling and normalization.
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
44 * dest - the destination vector of normals
47 TAG(transform_normalize_normals
)( const GLmatrix
*mat
,
50 const GLfloat
*lengths
,
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];
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
;
73 GLdouble len
= tx
*tx
+ ty
*ty
+ tz
*tz
;
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
);
81 out
[i
][0] = out
[i
][1] = out
[i
][2] = 0;
88 m0
*= scale
, m4
*= scale
, m8
*= scale
;
89 m1
*= scale
, m5
*= scale
, m9
*= scale
;
90 m2
*= scale
, m6
*= scale
, m10
*= scale
;
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
;
102 GLfloat len
= lengths
[i
];
103 out
[i
][0] = tx
* len
;
104 out
[i
][1] = ty
* len
;
105 out
[i
][2] = tz
* len
;
109 dest
->count
= in
->count
;
113 static void _XFORMAPI
114 TAG(transform_normalize_normals_no_rot
)( const GLmatrix
*mat
,
116 const GLvector4f
*in
,
117 const GLfloat
*lengths
,
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
;
134 const GLfloat ux
= from
[0], uy
= from
[1], uz
= from
[2];
140 GLdouble len
= tx
*tx
+ ty
*ty
+ tz
*tz
;
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
);
148 out
[i
][0] = out
[i
][1] = out
[i
][2] = 0;
161 const GLfloat ux
= from
[0], uy
= from
[1], uz
= from
[2];
167 GLfloat len
= lengths
[i
];
168 out
[i
][0] = tx
* len
;
169 out
[i
][1] = ty
* len
;
170 out
[i
][2] = tz
* len
;
174 dest
->count
= in
->count
;
178 static void _XFORMAPI
179 TAG(transform_rescale_normals_no_rot
)( const GLmatrix
*mat
,
181 const GLvector4f
*in
,
182 const GLfloat
*lengths
,
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];
198 GLfloat ux
= from
[0], uy
= from
[1], uz
= from
[2];
201 out
[i
][2] = uz
* m10
;
203 dest
->count
= in
->count
;
207 static void _XFORMAPI
208 TAG(transform_rescale_normals
)( const GLmatrix
*mat
,
210 const GLvector4f
*in
,
211 const GLfloat
*lengths
,
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.
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];
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
;
235 dest
->count
= in
->count
;
239 static void _XFORMAPI
240 TAG(transform_normals_no_rot
)( const GLmatrix
*mat
,
242 const GLvector4f
*in
,
243 const GLfloat
*lengths
,
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];
260 GLfloat ux
= from
[0], uy
= from
[1], uz
= from
[2];
263 out
[i
][2] = uz
* m10
;
265 dest
->count
= in
->count
;
269 static void _XFORMAPI
270 TAG(transform_normals
)( const GLmatrix
*mat
,
272 const GLvector4f
*in
,
273 const GLfloat
*lengths
,
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];
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
;
295 dest
->count
= in
->count
;
299 static void _XFORMAPI
300 TAG(normalize_normals
)( const GLmatrix
*mat
,
302 const GLvector4f
*in
,
303 const GLfloat
*lengths
,
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
;
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
;
326 const GLfloat x
= from
[0], y
= from
[1], z
= from
[2];
327 GLdouble len
= x
* x
+ y
* y
+ z
* z
;
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
);
341 dest
->count
= in
->count
;
345 static void _XFORMAPI
346 TAG(rescale_normals
)( const GLmatrix
*mat
,
348 const GLvector4f
*in
,
349 const GLfloat
*lengths
,
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
;
362 SCALE_SCALAR_3V( out
[i
], scale
, from
);
364 dest
->count
= in
->count
;
368 static void _XFORMAPI
369 TAG(init_c_norm_transform
)( void )
371 _mesa_normal_tab
[NORM_TRANSFORM_NO_ROT
] =
372 TAG(transform_normals_no_rot
);
374 _mesa_normal_tab
[NORM_TRANSFORM_NO_ROT
| NORM_RESCALE
] =
375 TAG(transform_rescale_normals_no_rot
);
377 _mesa_normal_tab
[NORM_TRANSFORM_NO_ROT
| NORM_NORMALIZE
] =
378 TAG(transform_normalize_normals_no_rot
);
380 _mesa_normal_tab
[NORM_TRANSFORM
] =
381 TAG(transform_normals
);
383 _mesa_normal_tab
[NORM_TRANSFORM
| NORM_RESCALE
] =
384 TAG(transform_rescale_normals
);
386 _mesa_normal_tab
[NORM_TRANSFORM
| NORM_NORMALIZE
] =
387 TAG(transform_normalize_normals
);
389 _mesa_normal_tab
[NORM_RESCALE
] =
390 TAG(rescale_normals
);
392 _mesa_normal_tab
[NORM_NORMALIZE
] =
393 TAG(normalize_normals
);