diff options
Diffstat (limited to 'u_math.c')
-rw-r--r-- | u_math.c | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/u_math.c b/u_math.c new file mode 100644 index 0000000..8169e15 --- /dev/null +++ b/u_math.c @@ -0,0 +1,151 @@ +/* +======================================================================= +This file is part of Redman's RT. + +Redman's RT is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Redman's RT is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Redman's RT. If not, see <http://www.gnu.org/licenses/>. +======================================================================= +*/ + +#include "common.h" + +vec_t V2Normalize( vec2_t v ) +{ + vec_t l, il; + + l = V2Length( v ); + + if( l ) + { + il = 1.0 / l; + V2Mul( v, v, il ); + } + else + V2Set( v, 0, 0 ); + + return l; +} + +vec_t V3Normalize( vec3_t v ) +{ + vec_t l, il; + + l = V3Length( v ); + + if( l ) + { + il = 1.0 / l; + V3Mul( v, v, il ); + } + else + V3Set( v, 0, 0, 0 ); + + return l; +} + +vec_t V4Normalize( vec4_t v ) +{ + vec_t l, il; + + l = V4Length( v ); + + if( l ) + { + il = 1.0 / l; + V4Mul( v, v, il ); + } + else + V4Set( v, 0, 0, 0, 0 ); + + return l; +} + +void V3Reflect( vec3_t out, const vec3_t in, const vec3_t normal ) +{ + vec_t dot; + + dot = V3Dot( in, normal ); + V3MA( out, in, -2.0 * dot, normal ); +} + +void V3AnglesToMatrix( m3_t out, const vec3_t angles ) +{ + m3_t M, Mx, My, Mz; + + M3RotX( Mx, angles[ 0 ] ); + M3RotY( My, angles[ 1 ] ); + M3RotZ( Mz, angles[ 2 ] ); + + M3Product( M, Mx, My ); + M3Product( out, M, Mz ); +} + +void V3HSVtoRGB( vec3_t out, const vec3_t in ) +{ + vec_t C, H_, X, m; + + C = in[ C_VALUE ] * in[ C_SATURATION ]; + + H_= in[ C_HUE ] / 60.0; + X = C * ( 1.0 - fabs( fmod( H_, 2.0 ) - 1.0 ) ); + + m = in[ C_VALUE ] - C; + + H_ = fmod( H_, 6.0f ); + + if( H_ >= 5.0 ) + V3Set( out, C, 0, X ); + else if( H_ >= 4.0 ) + V3Set( out, X, 0, C ); + else if( H_ >= 3.0 ) + V3Set( out, 0, X, C ); + else if( H_ >= 2.0 ) + V3Set( out, 0, C, X ); + else if( H_ >= 1.0 ) + V3Set( out, X, C, 0 ); + else + V3Set( out, C, X, 0 ); + + out[ C_RED ] += m; + out[ C_GREEN ] += m; + out[ C_BLUE ] += m; +} + +void V3RGBtoHSV( vec3_t out, const vec3_t in ) +{ + vec_t M, m, C; + + M = V1Max( V1Max( in[ 0 ], in[ 1 ] ), in[ 2 ] ); + m = V1Min( V1Min( in[ 0 ], in[ 1 ] ), in[ 2 ] ); + + C = M - m; + + if( V1Epscmp( C, 0, 1.0e-4 ) ) + out[ C_HUE ] = 0; + else if( V1Epscmp( M, in[ C_RED ], 1.0e-4 ) ) + out[ C_HUE ] = fmod( ( in[ C_GREEN ] - in[ C_BLUE ] ) / C, 6 ); + else if( V1Epscmp( M, in[ C_GREEN ], 1.0e-4 ) ) + out[ C_HUE ] = ( in[ C_BLUE ] - in[ C_RED ] ) / C + 2; + else + out[ C_HUE ] = ( in[ C_RED ] - in[ C_GREEN ] ) / C + 4; + + out[ C_HUE ] *= 60; + + out[ C_VALUE ] = M; + + if( V1Epscmp( C, 0, 1.0e-4 ) ) + out[ C_SATURATION ] = 0; + else + out[ C_SATURATION ] = C / out[ C_VALUE ]; +} + |