1 /* $Id: m_norm_tmp.h,v 1.12 2002/10/24 23:57:24 brianp 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.
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
41 * dest - the destination vector of normals
44 TAG(transform_normalize_normals
)( const GLmatrix
*mat
,
47 const GLfloat
*lengths
,
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];
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
;
70 GLdouble len
= tx
*tx
+ ty
*ty
+ tz
*tz
;
72 GLdouble scale
= 1.0 / GL_SQRT(len
);
73 out
[i
][0] = (GLfloat
) (tx
* scale
);
74 out
[i
][1] = (GLfloat
) (ty
* scale
);
75 out
[i
][2] = (GLfloat
) (tz
* scale
);
78 out
[i
][0] = out
[i
][1] = out
[i
][2] = 0;
85 m0
*= scale
, m4
*= scale
, m8
*= scale
;
86 m1
*= scale
, m5
*= scale
, m9
*= scale
;
87 m2
*= scale
, m6
*= scale
, m10
*= scale
;
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
;
99 GLfloat len
= lengths
[i
];
100 out
[i
][0] = tx
* len
;
101 out
[i
][1] = ty
* len
;
102 out
[i
][2] = tz
* len
;
106 dest
->count
= in
->count
;
110 static void _XFORMAPI
111 TAG(transform_normalize_normals_no_rot
)( const GLmatrix
*mat
,
113 const GLvector4f
*in
,
114 const GLfloat
*lengths
,
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
;
131 const GLfloat ux
= from
[0], uy
= from
[1], uz
= from
[2];
137 GLdouble len
= tx
*tx
+ ty
*ty
+ tz
*tz
;
139 GLdouble scale
= 1.0 / GL_SQRT(len
);
140 out
[i
][0] = (GLfloat
) (tx
* scale
);
141 out
[i
][1] = (GLfloat
) (ty
* scale
);
142 out
[i
][2] = (GLfloat
) (tz
* scale
);
145 out
[i
][0] = out
[i
][1] = out
[i
][2] = 0;
158 const GLfloat ux
= from
[0], uy
= from
[1], uz
= from
[2];
164 GLfloat len
= lengths
[i
];
165 out
[i
][0] = tx
* len
;
166 out
[i
][1] = ty
* len
;
167 out
[i
][2] = tz
* len
;
171 dest
->count
= in
->count
;
175 static void _XFORMAPI
176 TAG(transform_rescale_normals_no_rot
)( const GLmatrix
*mat
,
178 const GLvector4f
*in
,
179 const GLfloat
*lengths
,
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];
195 GLfloat ux
= from
[0], uy
= from
[1], uz
= from
[2];
198 out
[i
][2] = uz
* m10
;
200 dest
->count
= in
->count
;
204 static void _XFORMAPI
205 TAG(transform_rescale_normals
)( const GLmatrix
*mat
,
207 const GLvector4f
*in
,
208 const GLfloat
*lengths
,
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.
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];
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
;
232 dest
->count
= in
->count
;
236 static void _XFORMAPI
237 TAG(transform_normals_no_rot
)( const GLmatrix
*mat
,
239 const GLvector4f
*in
,
240 const GLfloat
*lengths
,
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];
257 GLfloat ux
= from
[0], uy
= from
[1], uz
= from
[2];
260 out
[i
][2] = uz
* m10
;
262 dest
->count
= in
->count
;
266 static void _XFORMAPI
267 TAG(transform_normals
)( const GLmatrix
*mat
,
269 const GLvector4f
*in
,
270 const GLfloat
*lengths
,
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];
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
;
292 dest
->count
= in
->count
;
296 static void _XFORMAPI
297 TAG(normalize_normals
)( const GLmatrix
*mat
,
299 const GLvector4f
*in
,
300 const GLfloat
*lengths
,
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
;
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
;
323 const GLfloat x
= from
[0], y
= from
[1], z
= from
[2];
324 GLdouble len
= x
* x
+ y
* y
+ z
* z
;
326 len
= 1.0 / GL_SQRT(len
);
327 out
[i
][0] = (GLfloat
) (x
* len
);
328 out
[i
][1] = (GLfloat
) (y
* len
);
329 out
[i
][2] = (GLfloat
) (z
* len
);
338 dest
->count
= in
->count
;
342 static void _XFORMAPI
343 TAG(rescale_normals
)( const GLmatrix
*mat
,
345 const GLvector4f
*in
,
346 const GLfloat
*lengths
,
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
;
359 SCALE_SCALAR_3V( out
[i
], scale
, from
);
361 dest
->count
= in
->count
;
365 static void _XFORMAPI
366 TAG(init_c_norm_transform
)( void )
368 _mesa_normal_tab
[NORM_TRANSFORM_NO_ROT
] =
369 TAG(transform_normals_no_rot
);
371 _mesa_normal_tab
[NORM_TRANSFORM_NO_ROT
| NORM_RESCALE
] =
372 TAG(transform_rescale_normals_no_rot
);
374 _mesa_normal_tab
[NORM_TRANSFORM_NO_ROT
| NORM_NORMALIZE
] =
375 TAG(transform_normalize_normals_no_rot
);
377 _mesa_normal_tab
[NORM_TRANSFORM
] =
378 TAG(transform_normals
);
380 _mesa_normal_tab
[NORM_TRANSFORM
| NORM_RESCALE
] =
381 TAG(transform_rescale_normals
);
383 _mesa_normal_tab
[NORM_TRANSFORM
| NORM_NORMALIZE
] =
384 TAG(transform_normalize_normals
);
386 _mesa_normal_tab
[NORM_RESCALE
] =
387 TAG(rescale_normals
);
389 _mesa_normal_tab
[NORM_NORMALIZE
] =
390 TAG(normalize_normals
);