/* Copyright (C) 1997, 1998, 1999, 2000 by Alex Pfaffe (Digital Dawn Graphics Inc) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _ddgUtil_Class_ #define _ddgUtil_Class_ #include "util/ddg.h" #ifdef CRYSTAL #include "cstypes.h" #endif #if !defined(WIN32) || (defined(OS_WIN32) && defined (COMP_GCC)) #ifdef DDG #include <strstream.h> #endif #include <stdlib.h> #define sqrtf sqrt #define cosf cos #define sinf sin #define atan2f atan2 #define fabsf fabs #define acosf acos #define logf log #define powf pow #endif #ifndef MAXFLOAT #define MAXFLOAT 99999999 #endif #ifndef M_PI #define M_PI 3.1415926535897932384626433832795028841971693993751 #endif #define DDG_BGET(VALUE,BITMASK) ((VALUE) & (BITMASK)) #define DDG_BSET(VALUE,BITMASK) (VALUE) |= (BITMASK) #define DDG_BCLEAR(VALUE,BITMASK) (VALUE) &= ~(BITMASK) #define sq(a) ((a)*(a)) // Some convenient angle functions. // Convert degrees to radians #define PITCH 0 #define YAW 1 #define ROLL 2 unsigned int const ddgAngle_res = 16; #define ddgPi M_PI class WEXP ddgAngle { static float _cosTable[180*ddgAngle_res+1]; static float _acosTable[180*ddgAngle_res+1]; public: ddgAngle(); inline static float degtorad(float d) { return (d * (float)M_PI / 180.0f); } inline static float radtodeg(float r) { return (r * 180.0f / (float)M_PI); } inline static float ttorad(float t) { return (t * 2.0f * (float)M_PI); } inline static float mod(float a) { return a >= 360.0f ? a - 360.0f : ( a < 0.0f ? a + 360.0f : a ); } inline static float cotf(float a) { return cosf(a)/sinf(a); } static float cos( float angle); inline static float sin( float angle) { return cos(angle-90.0f);} static float acos( float value); static float asin( float value) { return acos(1.0-value);} }; #undef min #undef max class WEXP ddgUtil { public: inline static float clamp(float v, float a,float b) { return (v) < a ? a : ((v) > b ? b : (v)); } inline static float linterp(float a, float b, float x) { return a + (b-a)*x;} inline static float binterp(float a, float b, float x) { if ( x < a ) return 0; if ( x >= b) return 1; x = (x - a ) / (b-a); return (x*x * (3 - 2*x)); } inline static float einterp(float a, float b, float x) { return a+(b-a)*(powf(2.0,8.0*x)/256.0); } inline static float cinterp(float a, float b, float x) { float f = (1 - ddgAngle::cos(x * 360))*0.5; return a*(1-f) + b * f; } inline static float wrap( float v, float a, float b) { return v < a ? v + b - a + 1: ( v > b ? v - b + a -1 : v ); } inline static float diff( float v1, float v2) { return v1 < v2 ? (v2-v1):(v1-v2); } inline static float idiff( float v1, float v2) { return v1 < v2 ? (v2-v1):(v1-v2); } inline static float max( float v1, float v2) { return v1 < v2 ? v2:v1; } inline static float min( float v1, float v2) { return v1 > v2 ? v2:v1; } inline static float abs( float v1) { return v1 > 0 ? v1:-v1; } static bool DetectSIMD(void); }; class WEXP ddgFileHelper { public: static void setDataDirectory( const char *dataDir ); static char *getFullFileName( const char *filename ); static void clear(void); }; class WEXP ddgConsoleMessage { static int _last; public: static void console(const char *msg); static void progress( char *s, int p, int total); static char *consoleMessage(void); #ifdef DDGSTREAM static ostrstream &consoleStream(void); #define ddgConsole(msg) { \ ddgConsoleMessage::consoleStream().seekp(0); \ ddgConsoleMessage::consoleStream() << msg << ends; \ ddgConsoleMessage::console(ddgConsoleMessage::consoleMessage()); \ ddgConsoleMessage::consoleStream().flush(); \ } #else // !DDGSTREAM #define ddgConsole(msg) #endif // DDGSTREAM }; class WEXP ddgListNode { ddgListNode* _next; public: inline ddgListNode() { _next = 0; } inline ddgListNode* next( ddgListNode* t = 0 ) { return (t? _next = t : _next); } }; class WEXP ddgList { unsigned int _no; ddgListNode* _head; public: ddgList() { _no = 0; _head = 0; } inline void add( ddgListNode* t) { t->next(_head); _head = t; _no++; } inline void remove( ddgListNode* t) { ddgListNode *c = _head, *p = 0; while(c) { if (t == c) { _no--; if (p) p->next(t->next()); if (p==_head) _head = t->next(); c=0; } else { p = c; c = c->next(); } } } inline unsigned int size() { return _no; } inline ddgListNode* head( ddgListNode *h = 0) { return (h? _head = h: _head); } }; // Useful macros to parse commandline arguments. // Assumes text array is in 'argv' and arg count is in 'argc'. // Assumes current arguments index is in 'argi'. // Assumes keywords are prefixed with '-' #define ddgArgMatchValue(s) (argi < argc && ddgStr::equal(argv[argi],"-"##s)) #define ddgArgMatch(s) (ddgArgMatchValue(s) && (++argi) < argc) #endif