1 /* $Id: m_norm_tmp.h,v 1.9 2002/01/05 14:12: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 #include "m_vertices.h"
40 * mat - the 4x4 transformation matrix
41 * scale - uniform scale factor of the transformation matrix (not always used)
42 * in - the source vector of normals
43 * lengths - length of each incoming normal (may be NULL) (a display list
45 * dest - the destination vector of normals
48 TAG(transform_normalize_normals
)( const GLmatrix
*mat
,
51 const GLfloat
*lengths
,
54 GLfloat (*out
)[3] = (GLfloat (*)[3])dest
->start
;
55 const GLfloat
*from
= in
->start
;
56 const GLuint stride
= in
->stride
;
57 const GLuint count
= in
->count
;
58 const GLfloat
*m
= mat
->inv
;
59 GLfloat m0
= m
[0], m4
= m
[4], m8
= m
[8];
60 GLfloat m1
= m
[1], m5
= m
[5], m9
= m
[9];
61 GLfloat m2
= m
[2], m6
= m
[6], m10
= m
[10];
68 const GLfloat ux
= from
[0], uy
= from
[1], uz
= from
[2];
69 tx
= ux
* m0
+ uy
* m1
+ uz
* m2
;
70 ty
= ux
* m4
+ uy
* m5
+ uz
* m6
;
71 tz
= ux
* m8
+ uy
* m9
+ uz
* m10
;
74 GLdouble len
= tx
*tx
+ ty
*ty
+ tz
*tz
;
76 GLdouble scale
= 1.0 / GL_SQRT(len
);
77 out
[i
][0] = (GLfloat
) (tx
* scale
);
78 out
[i
][1] = (GLfloat
) (ty
* scale
);
79 out
[i
][2] = (GLfloat
) (tz
* scale
);
82 out
[i
][0] = out
[i
][1] = out
[i
][2] = 0;
89 m0
*= scale
, m4
*= scale
, m8
*= scale
;
90 m1
*= scale
, m5
*= scale
, m9
*= scale
;
91 m2
*= scale
, m6
*= scale
, m10
*= scale
;
97 const GLfloat ux
= from
[0], uy
= from
[1], uz
= from
[2];
98 tx
= ux
* m0
+ uy
* m1
+ uz
* m2
;
99 ty
= ux
* m4
+ uy
* m5
+ uz
* m6
;
100 tz
= ux
* m8
+ uy
* m9
+ uz
* m10
;
103 GLfloat len
= lengths
[i
];
104 out
[i
][0] = tx
* len
;
105 out
[i
][1] = ty
* len
;
106 out
[i
][2] = tz
* len
;
110 dest
->count
= in
->count
;
114 static void _XFORMAPI
115 TAG(transform_normalize_normals_no_rot
)( const GLmatrix
*mat
,
117 const GLvector3f
*in
,
118 const GLfloat
*lengths
,
121 GLfloat (*out
)[3] = (GLfloat (*)[3])dest
->start
;
122 const GLfloat
*from
= in
->start
;
123 const GLuint stride
= in
->stride
;
124 const GLuint count
= in
->count
;
125 const GLfloat
*m
= mat
->inv
;
135 const GLfloat ux
= from
[0], uy
= from
[1], uz
= from
[2];
141 GLdouble len
= tx
*tx
+ ty
*ty
+ tz
*tz
;
143 GLdouble scale
= 1.0 / GL_SQRT(len
);
144 out
[i
][0] = (GLfloat
) (tx
* scale
);
145 out
[i
][1] = (GLfloat
) (ty
* scale
);
146 out
[i
][2] = (GLfloat
) (tz
* scale
);
149 out
[i
][0] = out
[i
][1] = out
[i
][2] = 0;
162 const GLfloat ux
= from
[0], uy
= from
[1], uz
= from
[2];
168 GLfloat len
= lengths
[i
];
169 out
[i
][0] = tx
* len
;
170 out
[i
][1] = ty
* len
;
171 out
[i
][2] = tz
* len
;
175 dest
->count
= in
->count
;
179 static void _XFORMAPI
180 TAG(transform_rescale_normals_no_rot
)( const GLmatrix
*mat
,
182 const GLvector3f
*in
,
183 const GLfloat
*lengths
,
186 GLfloat (*out
)[3] = (GLfloat (*)[3])dest
->start
;
187 const GLfloat
*from
= in
->start
;
188 const GLuint stride
= in
->stride
;
189 const GLuint count
= in
->count
;
190 const GLfloat
*m
= mat
->inv
;
191 const GLfloat m0
= scale
*m
[0];
192 const GLfloat m5
= scale
*m
[5];
193 const GLfloat m10
= scale
*m
[10];
199 GLfloat ux
= from
[0], uy
= from
[1], uz
= from
[2];
202 out
[i
][2] = uz
* m10
;
204 dest
->count
= in
->count
;
208 static void _XFORMAPI
209 TAG(transform_rescale_normals
)( const GLmatrix
*mat
,
211 const GLvector3f
*in
,
212 const GLfloat
*lengths
,
215 GLfloat (*out
)[3] = (GLfloat (*)[3])dest
->start
;
216 const GLfloat
*from
= in
->start
;
217 const GLuint stride
= in
->stride
;
218 const GLuint count
= in
->count
;
219 /* Since we are unlikely to have < 3 vertices in the buffer,
220 * it makes sense to pre-multiply by scale.
222 const GLfloat
*m
= mat
->inv
;
223 const GLfloat m0
= scale
*m
[0], m4
= scale
*m
[4], m8
= scale
*m
[8];
224 const GLfloat m1
= scale
*m
[1], m5
= scale
*m
[5], m9
= scale
*m
[9];
225 const GLfloat m2
= scale
*m
[2], m6
= scale
*m
[6], m10
= scale
*m
[10];
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
;
236 dest
->count
= in
->count
;
240 static void _XFORMAPI
241 TAG(transform_normals_no_rot
)( const GLmatrix
*mat
,
243 const GLvector3f
*in
,
244 const GLfloat
*lengths
,
247 GLfloat (*out
)[3] = (GLfloat (*)[3])dest
->start
;
248 const GLfloat
*from
= in
->start
;
249 const GLuint stride
= in
->stride
;
250 const GLuint count
= in
->count
;
251 const GLfloat
*m
= mat
->inv
;
252 const GLfloat m0
= m
[0];
253 const GLfloat m5
= m
[5];
254 const GLfloat m10
= m
[10];
261 GLfloat ux
= from
[0], uy
= from
[1], uz
= from
[2];
264 out
[i
][2] = uz
* m10
;
266 dest
->count
= in
->count
;
270 static void _XFORMAPI
271 TAG(transform_normals
)( const GLmatrix
*mat
,
273 const GLvector3f
*in
,
274 const GLfloat
*lengths
,
277 GLfloat (*out
)[3] = (GLfloat (*)[3])dest
->start
;
278 const GLfloat
*from
= in
->start
;
279 const GLuint stride
= in
->stride
;
280 const GLuint count
= in
->count
;
281 const GLfloat
*m
= mat
->inv
;
282 const GLfloat m0
= m
[0], m4
= m
[4], m8
= m
[8];
283 const GLfloat m1
= m
[1], m5
= m
[5], m9
= m
[9];
284 const GLfloat m2
= m
[2], m6
= m
[6], m10
= m
[10];
291 GLfloat ux
= from
[0], uy
= from
[1], uz
= from
[2];
292 out
[i
][0] = ux
* m0
+ uy
* m1
+ uz
* m2
;
293 out
[i
][1] = ux
* m4
+ uy
* m5
+ uz
* m6
;
294 out
[i
][2] = ux
* m8
+ uy
* m9
+ uz
* m10
;
296 dest
->count
= in
->count
;
300 static void _XFORMAPI
301 TAG(normalize_normals
)( const GLmatrix
*mat
,
303 const GLvector3f
*in
,
304 const GLfloat
*lengths
,
307 GLfloat (*out
)[3] = (GLfloat (*)[3])dest
->start
;
308 const GLfloat
*from
= in
->start
;
309 const GLuint stride
= in
->stride
;
310 const GLuint count
= in
->count
;
318 const GLfloat x
= from
[0], y
= from
[1], z
= from
[2];
319 GLfloat invlen
= lengths
[i
];
320 out
[i
][0] = x
* invlen
;
321 out
[i
][1] = y
* invlen
;
322 out
[i
][2] = z
* invlen
;
327 const GLfloat x
= from
[0], y
= from
[1], z
= from
[2];
328 GLdouble len
= x
* x
+ y
* y
+ z
* z
;
330 len
= 1.0 / GL_SQRT(len
);
331 out
[i
][0] = (GLfloat
) (x
* len
);
332 out
[i
][1] = (GLfloat
) (y
* len
);
333 out
[i
][2] = (GLfloat
) (z
* len
);
342 dest
->count
= in
->count
;
346 static void _XFORMAPI
347 TAG(rescale_normals
)( const GLmatrix
*mat
,
349 const GLvector3f
*in
,
350 const GLfloat
*lengths
,
353 GLfloat (*out
)[3] = (GLfloat (*)[3])dest
->start
;
354 const GLfloat
*from
= in
->start
;
355 const GLuint stride
= in
->stride
;
356 const GLuint count
= in
->count
;
363 SCALE_SCALAR_3V( out
[i
], scale
, from
);
365 dest
->count
= in
->count
;
369 static void _XFORMAPI
370 TAG(init_c_norm_transform
)( void )
372 _mesa_normal_tab
[NORM_TRANSFORM_NO_ROT
] =
373 TAG(transform_normals_no_rot
);
375 _mesa_normal_tab
[NORM_TRANSFORM_NO_ROT
| NORM_RESCALE
] =
376 TAG(transform_rescale_normals_no_rot
);
378 _mesa_normal_tab
[NORM_TRANSFORM_NO_ROT
| NORM_NORMALIZE
] =
379 TAG(transform_normalize_normals_no_rot
);
381 _mesa_normal_tab
[NORM_TRANSFORM
] =
382 TAG(transform_normals
);
384 _mesa_normal_tab
[NORM_TRANSFORM
| NORM_RESCALE
] =
385 TAG(transform_rescale_normals
);
387 _mesa_normal_tab
[NORM_TRANSFORM
| NORM_NORMALIZE
] =
388 TAG(transform_normalize_normals
);
390 _mesa_normal_tab
[NORM_RESCALE
] =
391 TAG(rescale_normals
);
393 _mesa_normal_tab
[NORM_NORMALIZE
] =
394 TAG(normalize_normals
);