/* Memonix, Viewizard Game Core ver 2.0 Copyright (c) 2001-2006 Michael Kurinnoy, Viewizard Games All Rights Reserved. Memonix game source codes available under "dual licensing" model. The licensing options available are: * Commercial Licensing. This is the appropriate option if you are creating proprietary applications and you are not prepared to distribute and share the source code of your application. Contact us for pricing at viewizard@viewizard.com * Open Source Licensing. This is the appropriate option if you want to share the source code of your application with everyone you distribute it to, and you also want to give them the right to share who uses it. You should have received a copy of the GNU General Public License version 3 with this source codes. If not, see . */ #include "Math.h" //------------------------------------------------------------------------------------ // Cosine Tab //------------------------------------------------------------------------------------ double Cos[360] = {1.000000,0.999848,0.999391,0.998630,0.997564,0.996195,0.994522, 0.992546,0.990268,0.987688,0.984808,0.981627,0.978148,0.974370, 0.970296,0.965926,0.961262,0.956305,0.951057,0.945519,0.939693, 0.933580,0.927184,0.920505,0.913545,0.906308,0.898794,0.891007, 0.882948,0.874620,0.866025,0.857167,0.848048,0.838671,0.829038, 0.819152,0.809017,0.798636,0.788011,0.777146,0.766044,0.754710, 0.743145,0.731354,0.719340,0.707107,0.694658,0.681998,0.669131, 0.656059,0.642788,0.629320,0.615661,0.601815,0.587785,0.573576, 0.559193,0.544639,0.529919,0.515038,0.500000,0.484810,0.469472, 0.453990,0.438371,0.422618,0.406737,0.390731,0.374607,0.358368, 0.342020,0.325568,0.309017,0.292372,0.275637,0.258819,0.241922, 0.224951,0.207912,0.190809,0.173648,0.156434,0.139173,0.121869, 0.104528,0.087156,0.069756,0.052336,0.034899,0.017452,0.000000, -0.017452,-0.034899,-0.052336,-0.069756,-0.087156,-0.104528, -0.121869,-0.139173,-0.156434,-0.173648,-0.190809,-0.207912, -0.224951,-0.241922,-0.258819,-0.275637,-0.292372,-0.309017, -0.325568,-0.342020,-0.358368,-0.374607,-0.390731,-0.406737, -0.422618,-0.438371,-0.453990,-0.469472,-0.484810,-0.500000, -0.515038,-0.529919,-0.544639,-0.559193,-0.573576,-0.587785, -0.601815,-0.615661,-0.629320,-0.642788,-0.656059,-0.669131, -0.681998,-0.694658,-0.707107,-0.719340,-0.731354,-0.743145, -0.754710,-0.766044,-0.777146,-0.788011,-0.798636,-0.809017, -0.819152,-0.829038,-0.838671,-0.848048,-0.857167,-0.866025, -0.874620,-0.882948,-0.891007,-0.898794,-0.906308,-0.913545, -0.920505,-0.927184,-0.933580,-0.939693,-0.945519,-0.951057, -0.956305,-0.961262,-0.965926,-0.970296,-0.974370,-0.978148, -0.981627,-0.984808,-0.987688,-0.990268,-0.992546,-0.994522, -0.996195,-0.997564,-0.998630,-0.999391,-0.999848,-1.000000, -0.999848,-0.999391,-0.998630,-0.997564,-0.996195,-0.994522, -0.992546,-0.990268,-0.987688,-0.984808,-0.981627,-0.978148, -0.974370,-0.970296,-0.965926,-0.961262,-0.956305,-0.951057, -0.945519,-0.939693,-0.933580,-0.927184,-0.920505,-0.913545, -0.906308,-0.898794,-0.891007,-0.882948,-0.874620,-0.866025, -0.857167,-0.848048,-0.838671,-0.829038,-0.819152,-0.809017, -0.798636,-0.788011,-0.777146,-0.766044,-0.754710,-0.743145, -0.731354,-0.719340,-0.707107,-0.694658,-0.681998,-0.669131, -0.656059,-0.642788,-0.629320,-0.615661,-0.601815,-0.587785, -0.573576,-0.559193,-0.544639,-0.529919,-0.515038,-0.500000, -0.484810,-0.469472,-0.453990,-0.438371,-0.422618,-0.406737, -0.390731,-0.374607,-0.358368,-0.342020,-0.325568,-0.309017, -0.292372,-0.275637,-0.258819,-0.241922,-0.224951,-0.207912, -0.190809,-0.173648,-0.156434,-0.139173,-0.121869,-0.104528, -0.087156,-0.069756,-0.052336,-0.034899,-0.017452,-0.000000, 0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869, 0.139173,0.156434,0.173648,0.190809,0.207912,0.224951,0.241922, 0.258819,0.275637,0.292372,0.309017,0.325568,0.342020, 0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.453990, 0.469472,0.484810,0.500000,0.515038,0.529919,0.544639,0.559193, 0.573576,0.587785,0.601815,0.615661,0.629320,0.642788,0.656059, 0.669131,0.681998,0.694658,0.707107,0.719340,0.731354,0.743145, 0.754710,0.766044,0.777146,0.788011,0.798636,0.809017,0.819152, 0.829038,0.838671,0.848048,0.857167,0.866025,0.874620,0.882948, 0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.933580, 0.939693,0.945519,0.951057,0.956305,0.961262,0.965926,0.970296, 0.974370,0.978148,0.981627,0.984808,0.987688,0.990268,0.992546, 0.994522,0.996195,0.997564,0.998630,0.999391,0.999848}; //------------------------------------------------------------------------------------ // Get Cosine //------------------------------------------------------------------------------------ double vw_dcos(int Angle) { return Cos[Angle]; } //------------------------------------------------------------------------------------ // Sine Tab //------------------------------------------------------------------------------------ double Sin[360] = {0.000000,0.017452,0.034899,0.052336,0.069756,0.087156, 0.104528,0.121869,0.139173,0.156434,0.173648,0.190809,0.207912, 0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568, 0.342020,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371, 0.453990,0.469472,0.484810,0.500000,0.515038,0.529919,0.544639, 0.559193,0.573576,0.587785,0.601815,0.615661,0.629320,0.642788, 0.656059,0.669131,0.681998,0.694658,0.707107,0.719340,0.731354, 0.743145,0.754710,0.766044,0.777146,0.788011,0.798636,0.809017, 0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,0.874620, 0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184, 0.933580,0.939693,0.945519,0.951057,0.956305,0.961262,0.965926, 0.970296,0.974370,0.978148,0.981627,0.984808,0.987688,0.990268, 0.992546,0.994522,0.996195,0.997564,0.998630,0.999391,0.999848, 1.000000,0.999848,0.999391,0.998630,0.997564,0.996195,0.994522, 0.992546,0.990268,0.987688,0.984808,0.981627,0.978148,0.974370, 0.970296,0.965926,0.961262,0.956305,0.951057,0.945519,0.939693, 0.933580,0.927184,0.920505,0.913545,0.906308,0.898794,0.891007, 0.882948,0.874620,0.866025,0.857167,0.848048,0.838671,0.829038, 0.819152,0.809017,0.798636,0.788011,0.777146,0.766044,0.754710, 0.743145,0.731354,0.719340,0.707107,0.694658,0.681998,0.669131, 0.656059,0.642788,0.629320,0.615661,0.601815,0.587785,0.573576, 0.559193,0.544639,0.529919,0.515038,0.500000,0.484810,0.469472, 0.453990,0.438371,0.422618,0.406737,0.390731,0.374607,0.358368, 0.342020,0.325568,0.309017,0.292372,0.275637,0.258819,0.241922, 0.224951,0.207912,0.190809,0.173648,0.156434,0.139173,0.121869, 0.104528,0.087156,0.069756,0.052336,0.034899,0.017452,0.000000, -0.017452,-0.034899,-0.052336,-0.069756,-0.087156,-0.104528, -0.121869,-0.139173,-0.156434,-0.173648,-0.190809,-0.207912, -0.224951,-0.241922,-0.258819,-0.275637,-0.292372,-0.309017, -0.325568,-0.342020,-0.358368,-0.374607,-0.390731,-0.406737, -0.422618,-0.438371,-0.453990,-0.469472,-0.484810,-0.500000, -0.515038,-0.529919,-0.544639,-0.559193,-0.573576,-0.587785, -0.601815,-0.615661,-0.629320,-0.642788,-0.656059,-0.669131, -0.681998,-0.694658,-0.707107,-0.719340,-0.731354,-0.743145, -0.754710,-0.766044,-0.777146,-0.788011,-0.798636,-0.809017, -0.819152,-0.829038,-0.838671,-0.848048,-0.857167,-0.866025, -0.874620,-0.882948,-0.891007,-0.898794,-0.906308,-0.913545, -0.920505,-0.927184,-0.933580,-0.939693,-0.945519,-0.951057, -0.956305,-0.961262,-0.965926,-0.970296,-0.974370,-0.978148, -0.981627,-0.984808,-0.987688,-0.990268,-0.992546,-0.994522, -0.996195,-0.997564,-0.998630,-0.999391,-0.999848,-1.000000, -0.999848,-0.999391,-0.998630,-0.997564,-0.996195,-0.994522, -0.992546,-0.990268,-0.987688,-0.984808,-0.981627,-0.978148, -0.974370,-0.970296,-0.965926,-0.961262,-0.956305,-0.951057, -0.945519,-0.939693,-0.933580,-0.927184,-0.920505,-0.913545, -0.906308,-0.898794,-0.891007,-0.882948,-0.874620,-0.866025, -0.857167,-0.848048,-0.838671,-0.829038,-0.819152,-0.809017, -0.798636,-0.788011,-0.777146,-0.766044,-0.754710,-0.743145, -0.731354,-0.719340,-0.707107,-0.694658,-0.681998,-0.669131, -0.656059,-0.642788,-0.629320,-0.615661,-0.601815,-0.587785, -0.573576,-0.559193,-0.544639,-0.529919,-0.515038,-0.500000, -0.484810,-0.469472,-0.453990,-0.438371,-0.422618,-0.406737, -0.390731,-0.374607,-0.358368,-0.342020,-0.325568,-0.309017, -0.292372,-0.275637,-0.258819,-0.241922,-0.224951,-0.207912, -0.190809,-0.173648,-0.156434,-0.139173,-0.121869,-0.104528, -0.087156,-0.069756,-0.052336,-0.034899,-0.017452}; //------------------------------------------------------------------------------------ // Get Sine //------------------------------------------------------------------------------------ double vw_dsin(int Angle) { return Sin[Angle]; } /* //------------------------------------------------------------------------------------ // Fast convert from float into long //------------------------------------------------------------------------------------ void vw_ftol(int *i, float f ) { __asm fld f; __asm mov edx, i __asm fistp [edx]; } */ //------------------------------------------------------------------------------------ // Fast convert from float double into int //------------------------------------------------------------------------------------ int vw_dtoi(double d) { const double t = d + 6755399441055744.0; return *((int *)(&t)); } /* //------------------------------------------------------------------------------------ // Fast convert float data into int (truncation) //------------------------------------------------------------------------------------ int vw_roundf(float f) { int n; __asm fld f __asm fistp n return n; } */ //------------------------------------------------------------------------------------ // Fast string comparison //------------------------------------------------------------------------------------ int vw_strcmp(const char *a, const char *b) { while(*a == *b) { if(*a == '\0')return 0; a++; b++; } return 1; } //------------------------------------------------------------------------------------ // Fast root (without sqrtf) //------------------------------------------------------------------------------------ #define ONE_AS_INTEGER ((DWORD)(0x3F800000)) #ifdef WIN32 // для MSVC используем float __fastcall ulrsqrt(float x) #else float ulrsqrt(const float & x) #endif { DWORD tmp = ((ONE_AS_INTEGER << 1) + ONE_AS_INTEGER - *(DWORD*)&x) >> 1; float y = *((float*)&tmp); // способ аналогично виндовому, но менее точный чем тот, что ниже y = (3.0f - x * (y * y)) * y * 0.5f; // remove for low accuracy return y; // второй способ, более точный... // return (y * (1.47f - 0.47f * x * y * y)); } float vw_sqrtf(float x) { // второй способ, с делением, более точный // return 1.0f/ulrsqrt(x); return x*ulrsqrt(x); } //------------------------------------------------------------------------------------ // Randomize float //------------------------------------------------------------------------------------ #include "MersenneTwister.h" float vw_Rand() { #ifdef WIN32 double thisTime=GetTickCount(); float M1=fmodf((float)thisTime,10.0f); float M2=fmodf((float)(thisTime/10),10.0f); float M3=fmodf((float)(thisTime/100),10.0f); float M4=fmodf((float)(thisTime/1000),10.0f); return (float)(rand()+M1+M2+M3+M4); #endif // WIN32 #ifdef __unix MTRand mtrand1; return (float)mtrand1.rand(RAND_MAX); #endif // unix } float vw_RandNum(float Max) { MTRand mtrand1; return (float)mtrand1.randExc(Max); } int vw_iRandNum(int Max) { MTRand mtrand1; return mtrand1.randInt(Max); } //------------------------------------------------------------------------------------ // Fast normalization... //------------------------------------------------------------------------------------ #define ONE_AS_INTEGER ((DWORD)(0x3F800000)) #ifdef WIN32 // для MSVC используем __fastcall float __fastcall InvSqrt(const float & x) #else float InvSqrt(const float & x) #endif { DWORD tmp = ((ONE_AS_INTEGER << 1) + ONE_AS_INTEGER - *(DWORD*)&x) >> 1; float y = *(float*)&tmp; return y * (1.47f - 0.47f * x * y * y); } void Normalise(VECTOR3D *v) { float L_squared, one_over_L; L_squared = (v->x * v->x) + (v->y * v->y) + (v->z * v->z); one_over_L = InvSqrt(L_squared); v->x = v->x * one_over_L; v->y = v->y * one_over_L; v->z = v->z * one_over_L; } //------------------------------------------------------------------------------------ // 3D Vector //------------------------------------------------------------------------------------ float VECTOR3D::Length() { return vw_sqrtf(x * x + y * y + z * z); } void VECTOR3D::Normalize() { Normalise(this); } void VECTOR3D::Multiply( VECTOR3D A) { float tV[3]; tV[0] = y * A.z - z * A.y; tV[1] = z * A.x - x * A.z; tV[2] = x * A.y - y * A.x; x = tV[0]; y = tV[1]; z = tV[2]; } //------------------------------------------------------------------------------------ // Get max //------------------------------------------------------------------------------------ float Max3(float a1,float a2,float a3) { if ((a1>=a2)&(a1>=a3)){return a1;} if ((a2>=a1)&(a2>=a3)){return a2;} if ((a3>=a1)&(a3>=a2)){return a3;} return a1; } //------------------------------------------------------------------------------------ // Get min //------------------------------------------------------------------------------------ float Min3(float a1,float a2,float a3) { if ((a1<=a2)&(a1<=a3)){return a1;} if ((a2<=a1)&(a2<=a3)){return a2;} if ((a3<=a1)&(a3<=a2)){return a3;} return a1; } //----------------------------------------------------------------------------- // Get Plane ABCD value, via 3 points on plane //----------------------------------------------------------------------------- void GetPlaneABCD(float *A, float *B, float *C, float *D, VECTOR3D Point1, VECTOR3D Point2, VECTOR3D Point3) { *A = (Point2.y-Point1.y)*(Point3.z-Point1.z)-(Point2.z-Point1.z)*(Point3.y-Point1.y); *B = (Point2.z-Point1.z)*(Point3.x-Point1.x)-(Point2.x-Point1.x)*(Point3.z-Point1.z); *C = (Point2.x-Point1.x)*(Point3.y-Point1.y)-(Point2.y-Point1.y)*(Point3.x-Point1.x); *D = -Point1.x*(Point2.y-Point1.y)*(Point3.z-Point1.z) -Point1.y*(Point2.z-Point1.z)*(Point3.x-Point1.x) -Point1.z*(Point2.x-Point1.x)*(Point3.y-Point1.y) +Point1.z*(Point2.y-Point1.y)*(Point3.x-Point1.x) +Point1.y*(Point2.x-Point1.x)*(Point3.z-Point1.z) +Point1.x*(Point2.z-Point1.z)*(Point3.y-Point1.y); } //------------------------------------------------------------------------------------ // Rotate point on Angle regard to point(0,0,0) //------------------------------------------------------------------------------------ const float p180 = 0.0174532925f; void RotatePoint(VECTOR3D *Point, VECTOR3D Angle) { float xTMP = Point->x; float yTMP = Point->y; float zTMP = Point->z; // X if (Angle.x != 0) { float a = Angle.x*p180; float c = cosf(a); float s = sinf(a); Point->y = yTMP*c + zTMP*s; Point->z = -yTMP*s + zTMP*c; xTMP = Point->x; yTMP = Point->y; zTMP = Point->z; } // Y if (Angle.y != 0) { float a = -Angle.y*p180; float c = cosf(a); float s = sinf(a); Point->x = xTMP*c + zTMP*s; Point->z = -xTMP*s + zTMP*c; xTMP = Point->x; yTMP = Point->y; zTMP = Point->z; } // Z if (Angle.z != 0) { float a = Angle.z*p180; float c = cosf(a); float s = sinf(a); Point->x = xTMP*c + yTMP*s; Point->y = -xTMP*s + yTMP*c; } } void RotatePointInv(VECTOR3D *Point, VECTOR3D Angle) { float xTMP = Point->x; float yTMP = Point->y; float zTMP = Point->z; // Z if (Angle.z != 0) { float a = Angle.z*p180; float c = cosf(a); float s = sinf(a); Point->x = xTMP*c + yTMP*s; Point->y = -xTMP*s + yTMP*c; xTMP = Point->x; yTMP = Point->y; zTMP = Point->z; } // Y if (Angle.y != 0) { float a = -Angle.y*p180; float c = cosf(a); float s = sinf(a); Point->x = xTMP*c + zTMP*s; Point->z = -xTMP*s + zTMP*c; xTMP = Point->x; yTMP = Point->y; zTMP = Point->z; } // X if (Angle.x != 0) { float a = Angle.x*p180; float c = cosf(a); float s = sinf(a); Point->y = yTMP*c + zTMP*s; Point->z = -yTMP*s + zTMP*c; } }