Too lazy to comment
This commit is contained in:
551
mod_xj18/my_progs/mathlib.qc
Normal file
551
mod_xj18/my_progs/mathlib.qc
Normal file
@@ -0,0 +1,551 @@
|
||||
/*======================================================================
|
||||
MATHLIB STUFF
|
||||
|
||||
Originally created by FrikaC
|
||||
Some functions provided by Kashua & LordHavoc & Preach
|
||||
|
||||
======================================================================*/
|
||||
|
||||
// for speed...
|
||||
float pi = 3.14159265;
|
||||
float OneEightyOverPi = 57.29577;
|
||||
float PiOverOneEighty = 0.017453;
|
||||
|
||||
float() crandom = { return 2*(random() - 0.5); };
|
||||
|
||||
// You can set the accuracy of mathlib by changing this value.
|
||||
// If unset, it defaults to 0.001
|
||||
float mathlib_accuracy; //accuracy of sqrt & pow
|
||||
|
||||
// Definition/list of all math functions
|
||||
float(float num) mathlib_sqrt;
|
||||
float(float num) mathlib_sin;
|
||||
float(float num) mathlib_cos;
|
||||
float(float a, float b) mathlib_fast_pow;
|
||||
float (float number, float exp) mathlib_bitshift;
|
||||
float(float a, float b) mod;
|
||||
float(float v) anglemod;
|
||||
float (float y1, float y2) angcomp;
|
||||
float (float a, float b) mathlib_min;
|
||||
float (float a, float b) mathlib_max;
|
||||
float(float minimum, float val, float maximum) mathlib_bound;
|
||||
vector() mathlib_randomvec;
|
||||
float (float num) rad2deg;
|
||||
float (float num) deg2rad;
|
||||
float(float theta) mathlib_tan;
|
||||
float(float y, float x) mathlib_atan2;
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Will return 0/1 if bitflag is present in bitvalue
|
||||
----------------------------------------------------------------------*/
|
||||
float(float bitvalue, float bitflag) mathlib_bitvalue =
|
||||
{
|
||||
return floor( (bitvalue & bitflag) / bitflag);
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
square root
|
||||
----------------------------------------------------------------------*/
|
||||
float(float num) mathlib_sqrt =
|
||||
{
|
||||
local float apr;
|
||||
|
||||
//this sets a level of accuracy, it's a global float
|
||||
if(mathlib_accuracy <= 0) mathlib_accuracy = 0.001;
|
||||
|
||||
if (num < mathlib_accuracy) return 0;
|
||||
if (num>1) apr = num;
|
||||
else apr = 1;
|
||||
do {
|
||||
apr = (num + (apr * apr)) / (2 * apr);
|
||||
}
|
||||
while (fabs((apr * apr) - num) > (num * mathlib_accuracy));
|
||||
return apr;
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
sine
|
||||
----------------------------------------------------------------------*/
|
||||
float(float num) mathlib_sin =
|
||||
{
|
||||
local vector ang,vf,vu,vr;
|
||||
|
||||
vf = v_forward;
|
||||
vu = v_up;
|
||||
vr = v_right;
|
||||
|
||||
ang = '0 1 0' * num;
|
||||
makevectors(ang);
|
||||
num = v_forward_y;
|
||||
|
||||
v_forward = vf;
|
||||
v_up = vu;
|
||||
v_right = vr;
|
||||
|
||||
return num;
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
cosine
|
||||
----------------------------------------------------------------------*/
|
||||
float(float num) mathlib_cos =
|
||||
{
|
||||
local vector ang,vf,vu,vr;
|
||||
|
||||
vf = v_forward;
|
||||
vu = v_up;
|
||||
vr = v_right;
|
||||
|
||||
ang = '0 1 0' * num;
|
||||
makevectors(ang);
|
||||
num = v_forward_x;
|
||||
|
||||
v_forward = vf;
|
||||
v_up = vu;
|
||||
v_right = vr;
|
||||
|
||||
return num;
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
pow
|
||||
|
||||
raise to a power
|
||||
|
||||
you ought not use this if the power you're raising to is constant
|
||||
ie, just use r * r * r for cubing, it's a lot faster
|
||||
----------------------------------------------------------------------*/
|
||||
float(float a, float b) mathlib_fast_pow =
|
||||
{
|
||||
local float fb, n, bit, factor;
|
||||
|
||||
fb = fabs(b);
|
||||
bit = 1;
|
||||
n = 1;
|
||||
factor = a;
|
||||
while (bit <= fb)
|
||||
{
|
||||
if (fb&bit)
|
||||
n = n * factor;
|
||||
factor = factor * factor;
|
||||
bit = bit * 2;
|
||||
}
|
||||
if (b < 0)
|
||||
return 1/n;
|
||||
else
|
||||
return n;
|
||||
};
|
||||
|
||||
float(float a, float b) mathlib_pow =
|
||||
{
|
||||
local float e1,e2,f,i;
|
||||
|
||||
if (mathlib_accuracy <= 0)
|
||||
mathlib_accuracy = 0.001;
|
||||
if (fabs(rint(b) - b) <= mathlib_accuracy)
|
||||
return mathlib_fast_pow(a, rint(b));
|
||||
|
||||
f = (a - 1) / (a + 1);
|
||||
//this is the first trick
|
||||
//we're essentially doing exp(b*log(a))
|
||||
//but the power series for log (1+x) is only defined for small x
|
||||
//however log x = 2 * arctanh((x-1)/(x+1)) which will converge for any x we choose
|
||||
|
||||
e1 = 0;
|
||||
e2 = 2 * f;
|
||||
i = 1;
|
||||
f = f * f;
|
||||
|
||||
// this calculates successive terms of arctanh
|
||||
//when the absolute value of a term drops
|
||||
//below accuracy we call it a day
|
||||
//note that this doesn't actually mean
|
||||
//the output is accurate to 0.001, there's no
|
||||
//direct bound on accuracy
|
||||
while(fabs(e2) > mathlib_accuracy)
|
||||
{
|
||||
e1 = e1 + e2;
|
||||
e2 = e2 * f * ((2 * i) - 1) / ((2 * i) + 1);
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
f = e2 = e1 * b;
|
||||
e1 = 1;
|
||||
i = 1;
|
||||
//same idea, this is the exponential function
|
||||
//which has a nice power series
|
||||
//same comments about accuracy apply, except
|
||||
//the rapid decay of terms mean it's probably
|
||||
//close to the true value of exp f, if not pow(a,b)
|
||||
while(fabs(e2) > mathlib_accuracy)
|
||||
{
|
||||
e1 = e1 + e2;
|
||||
i = i + 1;
|
||||
e2 = e2 * f / i;
|
||||
}
|
||||
return e1;
|
||||
} ;
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Bitshift
|
||||
----------------------------------------------------------------------*/
|
||||
float (float number, float exp) mathlib_bitshift =
|
||||
{
|
||||
local float bit, fexp;
|
||||
bit = 1;
|
||||
fexp = fabs(exp);
|
||||
number = rint(number);
|
||||
|
||||
while (bit <= fexp) {
|
||||
if (fexp & bit) {
|
||||
if (exp > 0) number = number * bit * 2;
|
||||
else number = floor(number / (bit * 2));
|
||||
}
|
||||
bit = bit * 2;
|
||||
}
|
||||
return number;
|
||||
};
|
||||
/*----------------------------------------------------------------------
|
||||
Remainder
|
||||
|
||||
Similar to C's % operator, but deals with
|
||||
negative numbers differently.
|
||||
----------------------------------------------------------------------*/
|
||||
float(float a, float b) mod =
|
||||
{
|
||||
return a - (floor(a / b) * b);
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
mathlib_anglemod
|
||||
|
||||
faster version of id's anglemod
|
||||
----------------------------------------------------------------------*/
|
||||
float(float v) anglemod =
|
||||
{
|
||||
return v - floor(v/360) * 360;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Original version from ai.qc
|
||||
/*float(float v) anglemod =
|
||||
{
|
||||
while (v >= 360)
|
||||
v = v - 360;
|
||||
while (v < 0)
|
||||
v = v + 360;
|
||||
return v;
|
||||
};
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
angcomp (part of FrikBot)
|
||||
|
||||
subtracts one angle from another
|
||||
----------------------------------------------------------------------*/
|
||||
float (float y1, float y2) angcomp =
|
||||
{
|
||||
y1 = anglemod(y1);
|
||||
y2 = anglemod(y2);
|
||||
|
||||
local float answer;
|
||||
answer = y1 - y2;
|
||||
if (answer > 180)
|
||||
answer = answer - 360;
|
||||
else if (answer < -180)
|
||||
answer = answer + 360;
|
||||
return answer;
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
min
|
||||
Returns the lesser of two (or more) numbers
|
||||
----------------------------------------------------------------------*/
|
||||
float (float a, float b) mathlib_min =
|
||||
{
|
||||
if (a<b)
|
||||
return a;
|
||||
else
|
||||
return b;
|
||||
};
|
||||
|
||||
float (float a, float b, float c) mathlib_min3 =
|
||||
{
|
||||
if (a<b)
|
||||
{
|
||||
if (c<a)
|
||||
return c;
|
||||
else
|
||||
return a;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (c<b)
|
||||
return c;
|
||||
else
|
||||
return b;
|
||||
}
|
||||
};
|
||||
|
||||
float (float a, float b, float c, float d) mathlib_min4 =
|
||||
{
|
||||
return mathlib_min(mathlib_min3(a,b,c),d);
|
||||
};
|
||||
float (float a, float b, float c, float d, float e) mathlib_min5 =
|
||||
{
|
||||
return mathlib_min3(mathlib_min3(a,b,c),d,e);
|
||||
};
|
||||
float (float a, float b, float c, float d, float e, float f) mathlib_min6 =
|
||||
{
|
||||
return mathlib_min(mathlib_min3(a,b,c), mathlib_min3(d,e,f));
|
||||
};
|
||||
float (float a, float b, float c, float d, float e, float f, float g) mathlib_min7 =
|
||||
{
|
||||
return mathlib_min3(mathlib_min3(a,b,c), mathlib_min3(d,e,f), g);
|
||||
};
|
||||
float (float a, float b, float c, float d, float e, float f, float g, float h) mathlib_min8 =
|
||||
{
|
||||
return mathlib_min3(mathlib_min3(a,b,c), mathlib_min3(d,e,f), mathlib_min(g, h));
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
max
|
||||
Returns the greater of two (or more) numbers
|
||||
----------------------------------------------------------------------*/
|
||||
float (float a, float b) mathlib_max =
|
||||
{
|
||||
if (a>b)
|
||||
return a;
|
||||
else
|
||||
return b;
|
||||
};
|
||||
float (float a, float b, float c) mathlib_max3 =
|
||||
{
|
||||
if (a>b)
|
||||
{
|
||||
if (c>a)
|
||||
return c;
|
||||
else
|
||||
return a;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (c>b)
|
||||
return c;
|
||||
else
|
||||
return b;
|
||||
}
|
||||
};
|
||||
float (float a, float b, float c, float d) mathlib_max4 =
|
||||
{
|
||||
return mathlib_max(mathlib_max3(a,b,c),d);
|
||||
};
|
||||
float (float a, float b, float c, float d, float e) mathlib_max5 =
|
||||
{
|
||||
return mathlib_max3(mathlib_max3(a,b,c),d,e);
|
||||
};
|
||||
float (float a, float b, float c, float d, float e, float f) mathlib_max6 =
|
||||
{
|
||||
return mathlib_max(mathlib_max3(a,b,c), mathlib_max3(d,e,f));
|
||||
};
|
||||
float (float a, float b, float c, float d, float e, float f, float g) mathlib_max7 =
|
||||
{
|
||||
return mathlib_max3(mathlib_max3(a,b,c), mathlib_max3(d,e,f), g);
|
||||
};
|
||||
float (float a, float b, float c, float d, float e, float f, float g, float h) mathlib_max8 =
|
||||
{
|
||||
return mathlib_max3(mathlib_max3(a,b,c), mathlib_max3(d,e,f), mathlib_max(g, h));
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
bound
|
||||
Returns a number bound to certain limits
|
||||
----------------------------------------------------------------------*/
|
||||
float(float minimum, float val, float maximum) mathlib_bound =
|
||||
{
|
||||
if (val<minimum)
|
||||
val=minimum;
|
||||
else if (val>minimum)
|
||||
val=maximum;
|
||||
return val;
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
randomvec
|
||||
Returns a random vector of length < 1
|
||||
----------------------------------------------------------------------*/
|
||||
vector () mathlib_randomvec =
|
||||
{
|
||||
local vector v;
|
||||
do
|
||||
{
|
||||
v_x = random() * 2 - 1;
|
||||
v_y = random() * 2 - 1;
|
||||
v_z = random() * 2 - 1;
|
||||
}
|
||||
while(vlen(v) > 1);
|
||||
return v;
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Radians <--> Degrees
|
||||
|
||||
Simple functions that convert radians to
|
||||
degrees.
|
||||
----------------------------------------------------------------------*/
|
||||
float (float num) rad2deg = { return num*OneEightyOverPi; };
|
||||
float (float num) deg2rad = { return num*PiOverOneEighty; };
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
TAN
|
||||
Changes v_forward, v_right, v_up
|
||||
----------------------------------------------------------------------*/
|
||||
float(float theta) mathlib_tan =
|
||||
{
|
||||
local vector ang; //temporary used to calculate trig values
|
||||
ang = '0 0 0';
|
||||
ang_y = theta; //assign theta to the yaw to simplify reasoning
|
||||
makevectors(ang);
|
||||
return v_forward_y / v_forward_x;
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Inverse TAN
|
||||
----------------------------------------------------------------------*/
|
||||
float(float y, float x) mathlib_atan2 =
|
||||
{
|
||||
local vector ang; //temporary used to calculate trig values
|
||||
ang = '0 0 0';
|
||||
ang_x = x;
|
||||
ang_y = y;
|
||||
return vectoyaw(ang);
|
||||
};
|
||||
|
||||
/* *********************************************************
|
||||
|
||||
!!!FTEQCC or FrikQCC only code follows !!!
|
||||
|
||||
This code allows the engine to accelerate math functions
|
||||
|
||||
If not needed, you can simply delete the rest of the file
|
||||
and call the mathlib functions above directly.
|
||||
|
||||
It checks for the extensions DP_QC_MINMAXBOUND,
|
||||
DP_QC_RANDOMVEC, DP_QC_SINCOSSQRTPOW, EXT_BITSHIFT
|
||||
|
||||
********************************************************* */
|
||||
/*
|
||||
var float (float num) sqrt;
|
||||
var float (float num) sin;
|
||||
var float (float num) cos;
|
||||
var float (float num, float exp) pow;
|
||||
var float (float number, float exp) bitshift;
|
||||
var float (float a, float b) min;
|
||||
var float (float a, float b, float c) min3;
|
||||
var float (float a, float b, float c, float d) min4;
|
||||
var float (float a, float b, float c, float d, float e) min5;
|
||||
var float (float a, float b, float c, float d, float e, float f) min6;
|
||||
var float (float a, float b, float c, float d, float e, float f, float g) min7;
|
||||
var float (float a, float b, float c, float d, float e, float f, float g, float h) min8;
|
||||
var float (float a, float b) max;
|
||||
var float (float a, float b, float c) max3;
|
||||
var float (float a, float b, float c, float d) max4;
|
||||
var float (float a, float b, float c, float d, float e) max5;
|
||||
var float (float a, float b, float c, float d, float e, float f) max6;
|
||||
var float (float a, float b, float c, float d, float e, float f, float g) max7;
|
||||
var float (float a, float b, float c, float d, float e, float f, float g, float h) max8;
|
||||
var float (float minimum, float val, float maximum) bound;
|
||||
var vector() randomvec;
|
||||
|
||||
float(float val) ext_sin = #60;
|
||||
float(float val) ext_cos = #61;
|
||||
float(float val) ext_sqrt = #62;
|
||||
vector() ext_randomvec = #91;
|
||||
float(float a, float b) ext_min = #94;
|
||||
float(float a, float b, float c) ext_min3 = #94;
|
||||
float(float a, float b, float c, float d) ext_min4 = #94;
|
||||
float(float a, float b, float c, float d, float e) ext_min5 = #94;
|
||||
float(float a, float b, float c, float d, float e, float f) ext_min6 = #94;
|
||||
float(float a, float b, float c, float d, float e, float f, float g) ext_min7 = #94;
|
||||
float(float a, float b, float c, float d, float e, float f, float g, float h) ext_min8 = #94;
|
||||
float(float a, float b) ext_max = #95;
|
||||
float(float a, float b, float c) ext_max3 = #95;
|
||||
float(float a, float b, float c, float d) ext_max4 = #95;
|
||||
float(float a, float b, float c, float d, float e) ext_max5 = #95;
|
||||
float(float a, float b, float c, float d, float e, float f) ext_max6 = #95;
|
||||
float(float a, float b, float c, float d, float e, float f, float g) ext_max7 = #95;
|
||||
float(float a, float b, float c, float d, float e, float f, float g, float h) ext_max8 = #95;
|
||||
float(float minimum, float val, float maximum) ext_bound = #96;
|
||||
float(float a, float b) ext_pow = #97;
|
||||
float(float number, float quantity) ext_bitshift = #218;
|
||||
|
||||
// This is DP extension, may need to comment out if already defined.
|
||||
float(string s) checkextension = #99;
|
||||
|
||||
// The engine sin/cos builtins use radians rather than degrees. This is less useful, so convert
|
||||
float(float val) wrap_sin = { return ext_sin(val*PiOverOneEighty); };
|
||||
float(float val) wrap_cos = { return ext_cos(val*PiOverOneEighty); };
|
||||
|
||||
// this must be called in worldspawn before using any above functions
|
||||
void () MathlibCheckBuiltins =
|
||||
{
|
||||
local float checkext;
|
||||
|
||||
sqrt = mathlib_sqrt;
|
||||
cos = mathlib_cos;
|
||||
sin = mathlib_sin;
|
||||
pow = mathlib_pow;
|
||||
randomvec = mathlib_randomvec;
|
||||
min = mathlib_min;
|
||||
min3 = mathlib_min3;
|
||||
min4 = mathlib_min4;
|
||||
min5 = mathlib_min5;
|
||||
min6 = mathlib_min6;
|
||||
min7 = mathlib_min7;
|
||||
min8 = mathlib_min8;
|
||||
max = mathlib_max;
|
||||
max3 = mathlib_max3;
|
||||
max4 = mathlib_max4;
|
||||
max5 = mathlib_max5;
|
||||
max6 = mathlib_max6;
|
||||
max7 = mathlib_max7;
|
||||
max8 = mathlib_max8;
|
||||
bound = mathlib_bound;
|
||||
bitshift = mathlib_bitshift;
|
||||
checkext = cvar("pr_checkextension");
|
||||
if (checkext)
|
||||
{
|
||||
if (checkextension("DP_QC_SINCOSSQRTPOW"))
|
||||
{
|
||||
sqrt = ext_sqrt;
|
||||
cos = wrap_cos;
|
||||
sin = wrap_sin;
|
||||
pow = ext_pow;
|
||||
}
|
||||
|
||||
if (checkextension("DP_QC_RANDOMVEC"))
|
||||
randomvec = ext_randomvec;
|
||||
if (checkextension("DP_QC_MINMAXBOUND"))
|
||||
{
|
||||
min = ext_min;
|
||||
min3 = ext_min3;
|
||||
min4 = ext_min4;
|
||||
min5 = ext_min5;
|
||||
min6 = ext_min6;
|
||||
min7 = ext_min7;
|
||||
min8 = ext_min8;
|
||||
max = ext_max;
|
||||
max3 = ext_max3;
|
||||
max4 = ext_max4;
|
||||
max5 = ext_max5;
|
||||
max6 = ext_max6;
|
||||
max7 = ext_max7;
|
||||
max8 = ext_max8;
|
||||
bound = ext_bound;
|
||||
}
|
||||
if (checkextension("EXT_BITSHIFT"))
|
||||
bitshift = ext_bitshift;
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user