//===========================================================================// // Copyright (C) Microsoft Corporation. All rights reserved. // //===========================================================================// #ifndef MATHFUNC_H #define MATHFUNC_H #ifndef STUFF_STUFF_HPP #include #endif // DESCRIBES A COORDINATE SYSTEM, OR FRAME OR REFERENCE class frameOfRef { public: Stuff::Vector3D i; Stuff::Vector3D j; Stuff::Vector3D k; frameOfRef(void); frameOfRef (frameOfRef ©) { *this = copy; } frameOfRef & set_i (Stuff::Vector3D &new_i) { i = new_i; return *this; } frameOfRef & set_j (Stuff::Vector3D &new_j) { j = new_j; return *this; } frameOfRef & set_k (Stuff::Vector3D &new_k) { k = new_k; return *this; } frameOfRef & operator =(frameOfRef &fr); frameOfRef & orthonormalize () { return orthonormalize_on_yaxis(); } frameOfRef & orthonormalize_on_xaxis (); frameOfRef & orthonormalize_on_yaxis (); frameOfRef & orthonormalize_on_zaxis (); frameOfRef & reset_to_world_frame (); frameOfRef & rotate_about_i (float &angle); frameOfRef & rotate_about_j (float &angle); frameOfRef & rotate_about_k (float &angle); frameOfRef & rotate_about_i_orthonormal (float &angle); frameOfRef & rotate_about_j_orthonormal (float &angle); frameOfRef & rotate_about_k_orthonormal (float &angle); frameOfRef & rotate(float &i_angle, float &j_angle, float &k_angle); frameOfRef & rotate(Stuff::Vector3D &rotation_vector); frameOfRef & trans_to_frame (frameOfRef &new_frame); frameOfRef & trans_from_frame (frameOfRef &old_frame); void trans_to_frame (Stuff::Vector3D &vector) { float vx = vector.x; float vy = vector.y; float vz = vector.z; vector.x = i.x*vx + i.y*vy + i.z*vz; vector.y = j.x*vx + j.y*vy + j.z*vz; vector.z = k.x*vx + k.y*vy + k.z*vz; } }; void Rotate (Stuff::Vector2DOf &vec, float angle); void Rotate (Stuff::Vector3D &vec, float angle); void RotateLight (Stuff::Vector3D &vec, float angle); void OppRotate (Stuff::Vector3D &vec, float angle); float distance_from (Stuff::Vector3D &v1, Stuff::Vector3D &v2); float my_acos (float val); float angle_from (Stuff::Vector2DOf&v1, Stuff::Vector2DOf &v2); float angle_from (Stuff::Vector3D &v1, Stuff::Vector3D &v2); float world_angle_between (Stuff::Vector3D &v1, Stuff::Vector3D &v2); Stuff::Vector3D relativePositionToPoint (Stuff::Vector3D point, float angle, float distance, unsigned long flags); long RandomNumber (long range); long SignedRandomNumber (long range); bool RollDice (long percent); _inline long float2long (float val) { //_ftol TRUNCS not rounds. Processor wants to round. Surely there is some flag to not have this happen? // There is but BOY is it slow. We will try Andy's Magical formula instead. // Doesn't work either. Major bug in Intel's FPU. // Will simply call long here now to insure working ok and address later. long result = long(val); return result; #if 0 float point5 = 0.49f; if (val < 0.0f) { __asm { fld val fadd point5 fistp result } } else { __asm { fld val fsub point5 fistp result } } return result; if (val > 0.0f) val -= 0.49999999f; else val += 0.49999999f; val += 3 << 22; return ((*(long*)&val)&0x007fffff) - 0x00400000; #endif } //--------------------------------------------------------------------------- _inline float mc2_atan2 (float f1, float f2) { //Return atan of f1/f2; float result = 1.570796f; //f2 is always assumed positive here!!! if (f2 > Stuff::SMALL) { __asm { fld f1 fld f2 fpatan fabs fstp result } } return result; } //--------------------------------------------------------------------------- _inline float fmax (float f1, float f2) { if (f1 > f2) return f1; else return f2; } //--------------------------------------------------------------------------- _inline float fmin (float f1, float f2) { if (f1 < f2) return f1; else return f2; } //--------------------------------------------------------------------------- _inline float sign (float f1) { if (f1 < 0.0f) return -1.0f; return 0.0f; } #endif