summaryrefslogtreecommitdiff
path: root/u_math.c
diff options
context:
space:
mode:
Diffstat (limited to 'u_math.c')
-rw-r--r--u_math.c151
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 ];
+}
+