Advertisement
Apjjm

ATDD Scripting: Vector3d

Jun 15th, 2012
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.92 KB | None | 0 0
  1. ///////////////////////////////
  2. //+ VECTOR CLASS
  3. ///////////////////////////////
  4. class Vec3
  5.  {
  6.    float x; float y; float z;
  7.    
  8.    //Constructors
  9.    Vec3()
  10.     { x = 0; y = 0; z = 0; }
  11.    
  12.    Vec3(float afX, float afY, float afZ)
  13.     { x = afX; y = afY; z=afZ; }
  14.  
  15.    Vec3(string &in asVecName)
  16.     { load(asVecName); }
  17.    
  18.    Vec3(float[] values)
  19.     { x = values[0]; y = values[1]; z = values[2]; }
  20.    
  21.    Vec3(Vec3 &in v1)
  22.     { x = v1.x; y = v1.y; z = v1.z; }
  23.    
  24.    //Save/load vector from a variable
  25.    void save(string &in asVecName)
  26.     {
  27.       SetLocalVarFloat(asVecName + "_VEC3_X",x);
  28.       SetLocalVarFloat(asVecName + "_VEC3_Y",y);
  29.       SetLocalVarFloat(asVecName + "_VEC3_Z",z);
  30.     }
  31.    void saveGlobal(string &in asVecName)
  32.     {
  33.       SetGlobalVarFloat(asVecName + "_VEC3_X",x);
  34.       SetGlobalVarFloat(asVecName + "_VEC3_Y",y);
  35.       SetGlobalVarFloat(asVecName + "_VEC3_Z",z);    
  36.     }
  37.    
  38.    
  39.    void load(string &in asVecName)
  40.     {
  41.       x = GetLocalVarFloat(asVecName + "_VEC3_X");
  42.       y = GetLocalVarFloat(asVecName + "_VEC3_Y");
  43.       z = GetLocalVarFloat(asVecName + "_VEC3_Z");
  44.     }
  45.    void loadGlobal(string &in asVecName)
  46.     {
  47.       x = GetGlobalVarFloat(asVecName + "_VEC3_X");
  48.       y = GetGlobalVarFloat(asVecName + "_VEC3_Y");
  49.       z = GetGlobalVarFloat(asVecName + "_VEC3_Z");
  50.     }
  51.    //Indexing Overload
  52.    float opIndex(uint idx)
  53.    {    
  54.       switch(idx)
  55.       {
  56.          case 0:
  57.             return x;
  58.          case 1:
  59.             return y;
  60.          case 2:
  61.             return z;
  62.       }
  63.       return 0;
  64.    }
  65.    
  66.     void opIndex(uint idx, float value)
  67.    {
  68.       switch(idx)
  69.       {
  70.          case 0:
  71.             x = value;
  72.          case 1:
  73.             y = value;
  74.          case 2:
  75.             z = value;
  76.       }
  77.    }
  78.    
  79.    // Equality operator
  80.     bool opEquals(const Vec3 &in v1) const
  81.       { return (x == v1.x) && (y == v1.y) && (z == v1.z); }
  82.    
  83.    // Compound assignment operators
  84.     void opAddAssign(const Vec3 &in v1)
  85.       { x = v1.x; y = v1.y; z=v1.z; }
  86.     void opSubAssign(const Vec3 &in v1)
  87.       { x = v1.x; y = v1.y; z=v1.z; }
  88.    
  89.    // Math operators
  90.     Vec3 opAdd(const Vec3 &in v1) const
  91.       { return Vec3(x+v1.x,y+v1.y,z+v1.z); }
  92.    Vec3 opAdd(const float &in n) const
  93.       { return Vec3(x+n,y+n,z+n); }
  94.    Vec3 opAdd(const int &in n) const
  95.       { return Vec3(x+n,y+n,z+n); }
  96.    
  97.     Vec3 opSub(const Vec3 &in v1) const
  98.       { return Vec3(x-v1.x,y-v1.y,z-v1.z); }
  99.    Vec3 opSub(const float &in n) const
  100.       { return Vec3(x-n,y-n,z-n); }
  101.    Vec3 opSub(const int &in n) const
  102.       { return Vec3(x-n,y-n,z-n); }
  103.    
  104.    //Dot Product / Multiplication
  105.     float opMul(const Vec3 &in v1) const
  106.       { return (x*v1.x) + (y*v1.y) + (z*v1.z); }
  107.    Vec3 opMul(const float &in n) const
  108.       { return Vec3(x*n,y*n,z*n); }
  109.    Vec3 opMul(const int &in n) const
  110.       { return Vec3(x*n,y*n,z*n); }
  111.      
  112.    //Cross product (^)
  113.    Vec3 opXor(const Vec3 &in v1) const
  114.       { return Vec3( y*v1.z - v1.y*z,
  115.                   z*v1.x - v1.z*x,
  116.                   x*v1.y - v1.x*y); }
  117.    
  118.    Vec3 opDiv(const float &in n) const
  119.       { return Vec3(x/n,y/n,z/n); }
  120.    Vec3 opDiv(const int &in n) const
  121.       { return Vec3(x/n,y/n,z/n); }
  122.    
  123.    //Length
  124.    float lengthSQR()
  125.       { return x*x + y*y + z*z; }
  126.    float length()
  127.       { return sqrt(x*x + y*y + z*z); }
  128.    Vec3 normalised()
  129.       { float n = length(); return Vec3(x/n,y/n,z/n); }
  130.    
  131.    //Named dot/cross product
  132.    float dot(const Vec3 &in v1)
  133.       { return opMul(v1); }
  134.    Vec3 cross(const Vec3 &in v1)
  135.       { return opXor(v1); }
  136.      
  137.    //Display
  138.    string ToString()
  139.       { return "(" + x + "," + y + "," + z + ")"; }
  140.    
  141.    //Parsing from a string representation. Returns true iff successful.
  142.    bool FromString(string &in asString)
  143.    {
  144.       float[] vals = parseStringToFloatArray(asString);
  145.       if(vals.length() < 3)
  146.         { AddDebugMessage("Invalid dimensions in vector parsed from array: " + asString,false);
  147.          return false; }
  148.       x = vals[0]; y=vals[1]; z=vals[2];
  149.       return true;
  150.    }
  151.  }
  152. ///////////////////////////////
  153. //- VECTOR CLASS
  154. ///////////////////////////////
  155.  ///////////////////////////////
  156. //+ MATH - Remove this section if you are already using MATH Library
  157. ///////////////////////////////
  158. const uint32 _SQRTITERATIONS=16; //Maximum number of iterations for sqrt computation
  159. const float  _SQRTDELTA=0.00001f; //Margin of error allowable if complete before iteration ceiling
  160. bool approx(float &in x, float &in y, float &in epsilon)
  161. {
  162.     float delta = x-y;
  163.     return ((delta>0?delta:-delta) <= (epsilon>0?epsilon:-epsilon));
  164. }
  165.  
  166. float sqrt(float &in x)
  167. {
  168.     if(x<=0) return 0; //Early out - not valid input.
  169.     uint32 i = 0;
  170.     float o = x * 0.5f;
  171.     while( i<_SQRTITERATIONS && !approx(o*o,x,_SQRTDELTA) && o != 0)
  172.     {
  173.         o = 0.5f * (o + x/o);
  174.         i++;
  175.     }
  176.     return o;
  177. }
  178. ///////////////////////////////
  179. //- MATH
  180. ///////////////////////////////
  181. ///////////////////////////////
  182. //+ String Parsing - Remove this section if you are already using PARSING Library
  183. ///////////////////////////////
  184. float[] parseStringToFloatArray(string &in asString)
  185.  {
  186.    float[] output = {};
  187.    int integer = 0;      //Integer part of the number
  188.    float decimal = 0;      //Decimal part of the number
  189.    int exponent = 0;      //Exponent of the number
  190.    bool negativeInteger = false; //Is the integer part negative
  191.    bool negativeExponent = false; //Is the exponent part negative
  192.    double dMul = 1;             //Multiplier for the decimal
  193.    bool readNumber = false;      //Read a number yet or not (stops +. etc returning 0's).
  194.    
  195.    //Parsing loop
  196.    int state = 0;
  197.    string temp = asString + "!"; //Add an invalid character to end of string
  198.    for(uint i=0; i<temp.length(); i++)
  199.     {
  200.       //Determine properties about this character
  201.       uint8 chr = temp[i];
  202.       int  digit = _parseDigit(chr);
  203.       int sign     = _parseSign(chr);
  204.       bool isExponent = _parseHasExponent(chr);
  205.       bool isDecimalP = _parseHasDecimalPoint(chr);
  206.       bool isWhitesp  = _parseHasWhitespace(chr);
  207.       bool isDigit    = digit != -1;
  208.      
  209.       switch(state)
  210.       {
  211.          case 0: //Initial state
  212.             {
  213.                if(sign != 0)      { negativeInteger=(sign<0); integer =0; state=1; } //Read +/-XX
  214.                else if(isDigit)   { integer = digit; state = 1; readNumber=true; } //Read N
  215.                else if(isDecimalP){ state = 2; } //Read .XX -> Assume 0.XX
  216.                break;
  217.             }
  218.          case 1: //Read the number part of the float
  219.             {
  220.                if(isDigit)         { integer = (integer * 10) + digit; readNumber=true; } //Read NNXX
  221.                else if(isDecimalP) { state = 2; }            //Read NN.XX
  222.                else if(isExponent && readNumber) { state = 3; } //Read NNeXX -> assume NN.0eXX
  223.                else if(readNumber) { state = -1; }            //Finished reading the number.
  224.                else                { state = 0;  }
  225.                break;
  226.             }
  227.          case 2: //Read the decimal part of the float
  228.             {
  229.                if(isDigit)         { decimal += float(digit) * dMul; dMul *= 0.1; readNumber=true; }
  230.                else if(isExponent && readNumber) { state = 3; }
  231.                else if(readNumber) { state = -1; }
  232.                else                { state = 0;  }
  233.                break;
  234.             }
  235.          case 3: //Ignore a single whitespace char after the exponent.
  236.             {
  237.                if(isDigit)         { exponent = digit; state = 5; } //Read NNeXX
  238.                else if(isWhitesp)  { state = 4; } //Read NNe XX
  239.                else if(sign != 0)  { negativeExponent=(sign<0); state = 5; }
  240.                else                { state = -1; }
  241.                break;
  242.             }
  243.          case 4: //Read a +/- Sign or a digit for the exponent
  244.             {
  245.                if(isDigit)         { exponent = digit; state = 5; } //Read NNe NX
  246.                else if(sign != 0)  { negativeExponent=(sign<0); state = 5; } //Read NNe +/-XX
  247.                else                { state = -1; }
  248.                break;
  249.             }
  250.          case 5: //Reading the exponent
  251.             {
  252.                if(isDigit) { exponent = (exponent * 10) + digit; } //Read NNe NX
  253.                else        { state = -1; }
  254.                break;
  255.             }
  256.       }
  257.       //At the end of a number?
  258.       if(state < 0)
  259.        {
  260.           //Construct the number & add it to the output array
  261.          int index = output.length(); output.resize(index+1);
  262.          output[index] = _parseFloatHelper(integer,decimal,exponent,negativeInteger,negativeExponent);
  263.          //Reset parsing state
  264.          state = 0; integer=0; decimal=0; exponent=0; dMul =1;
  265.          negativeInteger=false; negativeExponent=false; readNumber=false;
  266.          //This terminating char was possibly the start of next number. Start from this character
  267.          if(isDecimalP || sign!=0) i-=1;
  268.        }
  269.    }
  270.    
  271.    return output;
  272.  }
  273.  
  274. float _parseFloatHelper(int integer, float decimal, int exponent, bool negI, bool negE)
  275.  {
  276.    //Calculate the number with no exponent applied
  277.    float x = float(integer) + decimal * 0.1f;
  278.    //Apply 10^E
  279.    float mul = negE?0.1f:10.0f;
  280.    for(int i=0; i<exponent; i++)
  281.       x = x*mul;
  282.    //Apply sign of the number
  283.    return negI?-x:x;
  284.  }
  285. //+ Parsing Helper Functions
  286. int _parseDigit(uint8 digit) {
  287.     int d = digit-48; //48 is ASCII code for 0
  288.     return ((d >= 0)&&(d<=9)) ? d : -1;
  289. }
  290. int _parseSign(uint8 chr) {
  291.  if (chr == 45) return -1;
  292.  else if(chr == 43) return 1;
  293.  else return 0;
  294. }
  295. bool _parseHasExponent(uint8 chr) { return (chr == 69) || (chr == 101); }
  296. bool _parseHasDecimalPoint(uint8 chr) { return (chr==46); }
  297. bool _parseHasWhitespace(uint8 chr) { return (chr == 43)||(chr == 32); }
  298. //-
  299. ///////////////////////////////
  300. //- String Parsing
  301. ///////////////////////////////
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement