forked from teamnwah/openmw-tes3coop
600583cb89
git-svn-id: https://openmw.svn.sourceforge.net/svnroot/openmw/trunk@97 ea6a568a-9f4f-0410-981a-c910a81bb256
166 lines
5 KiB
D
166 lines
5 KiB
D
/*
|
|
Monster - an advanced game scripting language
|
|
Copyright (C) 2007-2009 Nicolay Korslund
|
|
Email: <korslund@gmail.com>
|
|
WWW: http://monster.snaptoad.com/
|
|
|
|
This file (math.d) is part of the Monster script language
|
|
package.
|
|
|
|
Monster is distributed as free software: you can redistribute it
|
|
and/or modify it under the terms of the GNU General Public License
|
|
version 3, as published by the Free Software Foundation.
|
|
|
|
This program 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
|
|
version 3 along with this program. If not, see
|
|
http://www.gnu.org/licenses/ .
|
|
|
|
*/
|
|
|
|
|
|
// Simple math functions
|
|
module monster.modules.math;
|
|
|
|
import monster.monster;
|
|
import std.math;
|
|
import monster.vm.mclass;
|
|
|
|
const char[] moduleDef =
|
|
"module math;
|
|
|
|
double E = 2.7182818284590452354;
|
|
double PI = 3.141592653589793238;
|
|
double DEGTORAD = 3.141592653590/180;
|
|
double RADTODEG = 180/3.141592653590;
|
|
|
|
native double sin(double x);
|
|
native double cos(double x);
|
|
native double tan(double x);
|
|
native double asin(double x);
|
|
native double acos(double x);
|
|
native double atan(double x);
|
|
native double atan2(double y, double x); // = atan(y/x)
|
|
native double sinh(double x);
|
|
native double cosh(double x);
|
|
native double tanh(double x);
|
|
native double asinh(double x);
|
|
native double acosh(double x);
|
|
native double atanh(double x);
|
|
|
|
native double sqrt(double x);
|
|
native double exp(double x); // e^x
|
|
native double exp2(double x); // 2^x
|
|
native double log(double x); // base e
|
|
native double log10(double x);// base 10
|
|
native double log2(double x); // base 2
|
|
|
|
native double pow(double x, double y); // x^y
|
|
native double ipow(double x, int n); // x^n (faster than pow)
|
|
|
|
native int abs(int x);
|
|
native double fabs(double x);
|
|
native double ceil(double x);
|
|
native double floor(double x);
|
|
native double round(double x); // rounds to nearest integer
|
|
native double trunc(double x);
|
|
|
|
native double hypot(double x, double y); // = sqrt(x*x+y*y)
|
|
native double cbrt(double x); // cube root
|
|
|
|
// Calculates polynomial a0 + x*a1 + x^2*a2 + x^3*a3 + ...
|
|
native double poly(double x, float[] A);
|
|
"; //"
|
|
|
|
version(Tango)
|
|
{
|
|
double fabs(double x) { return abs(x); }
|
|
}
|
|
|
|
void initMathModule()
|
|
{
|
|
static MonsterClass mc;
|
|
if(mc !is null) return;
|
|
|
|
mc = vm.loadString(moduleDef, "math");
|
|
|
|
mc.bind("sin", { stack.pushDouble(sin(stack.popDouble)); });
|
|
mc.bind("cos", { stack.pushDouble(cos(stack.popDouble)); });
|
|
mc.bind("tan", { stack.pushDouble(tan(stack.popDouble)); });
|
|
mc.bind("asin", { stack.pushDouble(asin(stack.popDouble)); });
|
|
mc.bind("acos", { stack.pushDouble(acos(stack.popDouble)); });
|
|
mc.bind("atan", { stack.pushDouble(atan(stack.popDouble)); });
|
|
|
|
mc.bind("sinh", { stack.pushDouble(sinh(stack.popDouble)); });
|
|
mc.bind("cosh", { stack.pushDouble(cosh(stack.popDouble)); });
|
|
mc.bind("tanh", { stack.pushDouble(tanh(stack.popDouble)); });
|
|
mc.bind("asinh", { stack.pushDouble(asinh(stack.popDouble)); });
|
|
mc.bind("acosh", { stack.pushDouble(acosh(stack.popDouble)); });
|
|
mc.bind("atanh", { stack.pushDouble(atanh(stack.popDouble)); });
|
|
|
|
mc.bind("atan2",
|
|
{
|
|
// Remember to pop the variables in the reverse order
|
|
auto x = stack.popDouble;
|
|
stack.pushDouble(atan2(stack.popDouble, x));
|
|
});
|
|
|
|
mc.bind("sqrt", { stack.pushDouble(sqrt(stack.popDouble)); });
|
|
mc.bind("exp", { stack.pushDouble(exp(stack.popDouble)); });
|
|
mc.bind("exp2", { stack.pushDouble(exp2(stack.popDouble)); });
|
|
mc.bind("log", { stack.pushDouble(log(stack.popDouble)); });
|
|
mc.bind("log2", { stack.pushDouble(log2(stack.popDouble)); });
|
|
mc.bind("log10", { stack.pushDouble(log10(stack.popDouble)); });
|
|
|
|
mc.bind("pow",
|
|
{
|
|
auto x = stack.popDouble;
|
|
stack.pushDouble(pow(stack.popDouble, x));
|
|
});
|
|
mc.bind("ipow",
|
|
{
|
|
auto x = stack.popInt;
|
|
stack.pushDouble(pow(cast(real)stack.popDouble, x));
|
|
});
|
|
|
|
mc.bind("abs", { stack.pushDouble(abs(stack.popDouble)); });
|
|
mc.bind("fabs", { stack.pushDouble(fabs(stack.popDouble)); });
|
|
mc.bind("ceil", { stack.pushDouble(ceil(stack.popDouble)); });
|
|
mc.bind("floor", { stack.pushDouble(floor(stack.popDouble)); });
|
|
mc.bind("round", { stack.pushDouble(round(stack.popDouble)); });
|
|
mc.bind("trunc", { stack.pushDouble(trunc(stack.popDouble)); });
|
|
|
|
// Order doesn't matter here
|
|
mc.bind("hypot", { stack.pushDouble(hypot(stack.popDouble,
|
|
stack.popDouble)); });
|
|
|
|
mc.bind("cbrt", { stack.pushDouble(cbrt(stack.popDouble)); });
|
|
|
|
mc.bind("poly", &npoly);
|
|
}
|
|
|
|
// Implement this ourselves, since phobos doesn't use the types we
|
|
// want
|
|
double poly(double x, float A[])
|
|
{
|
|
// Use 'real' internally for higher precision
|
|
real r = A[$-1];
|
|
foreach_reverse(c; A[0..$-1])
|
|
{
|
|
r *= x;
|
|
r += c;
|
|
}
|
|
return r;
|
|
}
|
|
|
|
// double poly(double x, float[] A);
|
|
void npoly()
|
|
{
|
|
auto arf = stack.popArray();
|
|
assert(arf.elemSize == 1);
|
|
stack.pushDouble(poly(stack.popDouble, arf.farr));
|
|
}
|