Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Nov 2, 2008, 12:38:26 PM (16 years ago)
Author:
rgrieder
Message:

Moved all util classes and functions to orxonox namespace.
Converted all code to 4 spaces/tab in util.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/branches/objecthierarchy/src/util/Math.cc

    r2019 r2111  
    3838#include "SubString.h"
    3939
    40 /**
    41     @brief Function for writing a Radian to a stream.
    42 */
    43 std::ostream& operator<<(std::ostream& out, const orxonox::Radian& radian)
     40namespace orxonox
    4441{
    45     out << radian.valueRadians();
    46     return out;
     42    /**
     43        @brief Function for writing a Radian to a stream.
     44    */
     45    std::ostream& operator<<(std::ostream& out, const orxonox::Radian& radian)
     46    {
     47        out << radian.valueRadians();
     48        return out;
     49    }
     50
     51    /**
     52        @brief Function for reading a Radian from a stream.
     53    */
     54    std::istream& operator>>(std::istream& in, orxonox::Radian& radian)
     55    {
     56        float temp;
     57        in >> temp;
     58        radian = temp;
     59        return in;
     60    }
     61
     62    /**
     63        @brief Function for writing a Degree to a stream.
     64    */
     65    std::ostream& operator<<(std::ostream& out, const orxonox::Degree& degree)
     66    {
     67        out << degree.valueDegrees();
     68        return out;
     69    }
     70
     71    /**
     72        @brief Function for reading a Degree from a stream.
     73    */
     74    std::istream& operator>>(std::istream& in, orxonox::Degree& degree)
     75    {
     76        float temp;
     77        in >> temp;
     78        degree = temp;
     79        return in;
     80    }
     81
     82
     83    /**
     84        @brief Gets the angle between my viewing direction and the direction to the position of the other object.
     85        @param myposition My position
     86        @param mydirection My viewing direction
     87        @param otherposition The position of the other object
     88        @return The angle
     89
     90        @example
     91        If the other object is exactly in front of me, the function returns 0.
     92        If the other object is exactly behind me, the function returns pi.
     93        If the other object is exactly right/left to me (or above/below), the function returns pi/2.
     94    */
     95    float getAngle(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& otherposition)
     96    {
     97        orxonox::Vector3 distance = otherposition - myposition;
     98        float distancelength = distance.length();
     99        if (distancelength == 0)
     100            return 0;
     101        else
     102            return acos(clamp<float>(mydirection.dotProduct(distance) / distancelength, -1, 1));
     103    }
     104
     105    /**
     106        @brief Gets the 2D viewing direction (up/down, left/right) to the position of the other object.
     107        @param myposition My position
     108        @param mydirection My viewing direction
     109        @param myorthonormal My orthonormalvector (pointing upwards through my head)
     110        @param otherposition The position of the other object
     111        @return The viewing direction
     112
     113        @example
     114        If the other object is exactly in front of me, the function returns Vector2(0, 0).
     115        If the other object is exactly at my left, the function returns Vector2(-1, 0).
     116        If the other object is exactly at my right, the function returns Vector2(1, 0).
     117        If the other object is only a bit at my right, the function still returns Vector2(1, 0).
     118        If the other object is exactly above me, the function returns Vector2(0, 1).
     119    */
     120    orxonox::Vector2 get2DViewdirection(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition)
     121    {
     122        orxonox::Vector3 distance = otherposition - myposition;
     123
     124        // project difference vector on our plane
     125        orxonox::Vector3 projection = Ogre::Plane(mydirection, myposition).projectVector(distance);
     126
     127        float projectionlength = projection.length();
     128        if (projectionlength == 0) return orxonox::Vector2(0, 0);
     129        float angle = acos(clamp<float>(myorthonormal.dotProduct(projection) / projectionlength, -1, 1));
     130
     131        if ((mydirection.crossProduct(myorthonormal)).dotProduct(distance) > 0)
     132            return orxonox::Vector2(sin(angle), cos(angle));
     133        else
     134            return orxonox::Vector2(-sin(angle), cos(angle));
     135    }
     136
     137    /**
     138        @brief Gets the 2D viewing direction (up/down, left/right) to the position of the other object, multiplied with the viewing distance to the object (0° = 0, 180° = 1).
     139        @param myposition My position
     140        @param mydirection My viewing direction
     141        @param myorthonormal My orthonormalvector (pointing upwards through my head)
     142        @param otherposition The position of the other object
     143        @return The viewing direction
     144
     145        @example
     146        If the other object is exactly in front of me, the function returns Vector2(0, 0).
     147        If the other object is exactly at my left, the function returns Vector2(-0.5, 0).
     148        If the other object is exactly at my right, the function returns Vector2(0.5, 0).
     149        If the other object is only a bit at my right, the function still returns Vector2(0.01, 0).
     150        If the other object is exactly above me, the function returns Vector2(0, 0.5).
     151    */
     152    orxonox::Vector2 get2DViewcoordinates(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition)
     153    {
     154        orxonox::Vector3 distance = otherposition - myposition;
     155
     156        // project difference vector on our plane
     157        orxonox::Vector3 projection = Ogre::Plane(mydirection, myposition).projectVector(distance);
     158
     159        float projectionlength = projection.length();
     160        if (projectionlength == 0) return orxonox::Vector2(0, 0);
     161        float angle = acos(clamp<float>(myorthonormal.dotProduct(projection) / projectionlength, -1, 1));
     162
     163        float distancelength = distance.length();
     164        if (distancelength == 0) return orxonox::Vector2(0, 0);
     165        float radius = acos(clamp<float>(mydirection.dotProduct(distance) / distancelength, -1, 1)) / Ogre::Math::PI;
     166
     167        if ((mydirection.crossProduct(myorthonormal)).dotProduct(distance) > 0)
     168            return orxonox::Vector2(sin(angle) * radius, cos(angle) * radius);
     169        else
     170            return orxonox::Vector2(-sin(angle) * radius, cos(angle) * radius);
     171    }
     172
     173    /**
     174        @brief Returns the predicted position I have to aim at, if I want to hit a moving target with a moving projectile.
     175        @param myposition My position
     176        @param projectilespeed The speed of my projectile
     177        @param targetposition The position of my target
     178        @param targetvelocity The velocity of my target
     179        @return The predicted position
     180
     181        The function predicts the position based on a linear velocity of the target. If the target changes speed or direction, the projectile will miss.
     182    */
     183    orxonox::Vector3 getPredictedPosition(const orxonox::Vector3& myposition, float projectilespeed, const orxonox::Vector3& targetposition, const orxonox::Vector3& targetvelocity)
     184    {
     185        float squaredProjectilespeed = projectilespeed * projectilespeed;
     186        orxonox::Vector3 distance = targetposition - myposition;
     187        float a = distance.squaredLength();
     188        float b = 2 * (distance.x + distance.y + distance.z) * (targetvelocity.x + targetvelocity.y + targetvelocity.z);
     189        float c = targetvelocity.squaredLength();
     190
     191        float temp = 4*squaredProjectilespeed*c + a*a - 4*b*c;
     192        if (temp < 0)
     193            return orxonox::Vector3::ZERO;
     194
     195        temp = sqrt(temp);
     196        float time = (temp + a) / (2 * (squaredProjectilespeed - b));
     197        return (targetposition + targetvelocity * time);
     198    }
     199
     200    unsigned long getUniqueNumber()
     201    {
     202        static unsigned long aNumber = 135;
     203        return aNumber++;
     204    }
     205
     206
     207    //////////////////////////
     208    // Conversion functions //
     209    //////////////////////////
     210
     211    // std::string to Vector2
     212    bool ConverterFallback<std::string, orxonox::Vector2>::convert(orxonox::Vector2* output, const std::string& input)
     213    {
     214        size_t opening_parenthesis, closing_parenthesis = input.find(')');
     215        if ((opening_parenthesis = input.find('(')) == std::string::npos)
     216            opening_parenthesis = 0;
     217        else
     218            opening_parenthesis++;
     219
     220        SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis),
     221                         ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');
     222        if (tokens.size() >= 2)
     223        {
     224            if (!ConvertValue(&(output->x), tokens[0]))
     225                return false;
     226            if (!ConvertValue(&(output->y), tokens[1]))
     227                return false;
     228
     229            return true;
     230        }
     231        return false;
     232    }
     233
     234    // std::string to Vector3
     235    bool ConverterFallback<std::string, orxonox::Vector3>::convert(orxonox::Vector3* output, const std::string& input)
     236    {
     237        size_t opening_parenthesis, closing_parenthesis = input.find(')');
     238        if ((opening_parenthesis = input.find('(')) == std::string::npos)
     239            opening_parenthesis = 0;
     240        else
     241            opening_parenthesis++;
     242
     243        SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis),
     244                         ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');
     245        if (tokens.size() >= 3)
     246        {
     247            if (!ConvertValue(&(output->x), tokens[0]))
     248                return false;
     249            if (!ConvertValue(&(output->y), tokens[1]))
     250                return false;
     251            if (!ConvertValue(&(output->z), tokens[2]))
     252                return false;
     253
     254            return true;
     255        }
     256        return false;
     257    }
     258
     259    // std::string to Vector4
     260    bool ConverterFallback<std::string, orxonox::Vector4>::convert(orxonox::Vector4* output, const std::string& input)
     261    {
     262        size_t opening_parenthesis, closing_parenthesis = input.find(')');
     263        if ((opening_parenthesis = input.find('(')) == std::string::npos)
     264            opening_parenthesis = 0;
     265        else
     266            opening_parenthesis++;
     267
     268        SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis),
     269                         ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');
     270        if (tokens.size() >= 4)
     271        {
     272            if (!ConvertValue(&(output->x), tokens[0]))
     273                return false;
     274            if (!ConvertValue(&(output->y), tokens[1]))
     275                return false;
     276            if (!ConvertValue(&(output->z), tokens[2]))
     277                return false;
     278            if (!ConvertValue(&(output->w), tokens[3]))
     279                return false;
     280
     281            return true;
     282        }
     283        return false;
     284    }
     285
     286    // std::string to Quaternion
     287    bool ConverterFallback<std::string, orxonox::Quaternion>::convert(orxonox::Quaternion* output, const std::string& input)
     288    {
     289        size_t opening_parenthesis, closing_parenthesis = input.find(')');
     290        if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; }
     291
     292        SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');
     293        if (tokens.size() >= 4)
     294        {
     295            if (!ConvertValue(&(output->w), tokens[0]))
     296                return false;
     297            if (!ConvertValue(&(output->x), tokens[1]))
     298                return false;
     299            if (!ConvertValue(&(output->y), tokens[2]))
     300                return false;
     301            if (!ConvertValue(&(output->z), tokens[3]))
     302                return false;
     303
     304            return true;
     305        }
     306        return false;
     307    }
     308
     309    // std::string to ColourValue
     310    bool ConverterFallback<std::string, orxonox::ColourValue>::convert(orxonox::ColourValue* output, const std::string& input)
     311    {
     312        size_t opening_parenthesis, closing_parenthesis = input.find(')');
     313        if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; }
     314
     315        SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');
     316        if (tokens.size() >= 3)
     317        {
     318            if (!ConvertValue(&(output->r), tokens[0]))
     319                return false;
     320            if (!ConvertValue(&(output->g), tokens[1]))
     321                return false;
     322            if (!ConvertValue(&(output->b), tokens[2]))
     323                return false;
     324            if (tokens.size() >= 4)
     325            {
     326                if (!ConvertValue(&(output->a), tokens[3]))
     327                    return false;
     328            }
     329            else
     330                output->a = 1.0;
     331
     332            return true;
     333        }
     334        return false;
     335    }
    47336}
    48 
    49 /**
    50     @brief Function for reading a Radian from a stream.
    51 */
    52 std::istream& operator>>(std::istream& in, orxonox::Radian& radian)
    53 {
    54     float temp;
    55     in >> temp;
    56     radian = temp;
    57     return in;
    58 }
    59 
    60 /**
    61     @brief Function for writing a Degree to a stream.
    62 */
    63 std::ostream& operator<<(std::ostream& out, const orxonox::Degree& degree)
    64 {
    65     out << degree.valueDegrees();
    66     return out;
    67 }
    68 
    69 /**
    70     @brief Function for reading a Degree from a stream.
    71 */
    72 std::istream& operator>>(std::istream& in, orxonox::Degree& degree)
    73 {
    74     float temp;
    75     in >> temp;
    76     degree = temp;
    77     return in;
    78 }
    79 
    80 
    81 /**
    82     @brief Gets the angle between my viewing direction and the direction to the position of the other object.
    83     @param myposition My position
    84     @param mydirection My viewing direction
    85     @param otherposition The position of the other object
    86     @return The angle
    87 
    88     @example
    89     If the other object is exactly in front of me, the function returns 0.
    90     If the other object is exactly behind me, the function returns pi.
    91     If the other object is exactly right/left to me (or above/below), the function returns pi/2.
    92 */
    93 float getAngle(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& otherposition)
    94 {
    95     orxonox::Vector3 distance = otherposition - myposition;
    96     float distancelength = distance.length();
    97     if (distancelength == 0)
    98         return 0;
    99     else
    100         return acos(clamp<float>(mydirection.dotProduct(distance) / distancelength, -1, 1));
    101 }
    102 
    103 /**
    104     @brief Gets the 2D viewing direction (up/down, left/right) to the position of the other object.
    105     @param myposition My position
    106     @param mydirection My viewing direction
    107     @param myorthonormal My orthonormalvector (pointing upwards through my head)
    108     @param otherposition The position of the other object
    109     @return The viewing direction
    110 
    111     @example
    112     If the other object is exactly in front of me, the function returns Vector2(0, 0).
    113     If the other object is exactly at my left, the function returns Vector2(-1, 0).
    114     If the other object is exactly at my right, the function returns Vector2(1, 0).
    115     If the other object is only a bit at my right, the function still returns Vector2(1, 0).
    116     If the other object is exactly above me, the function returns Vector2(0, 1).
    117 */
    118 orxonox::Vector2 get2DViewdirection(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition)
    119 {
    120     orxonox::Vector3 distance = otherposition - myposition;
    121 
    122     // project difference vector on our plane
    123     orxonox::Vector3 projection = Ogre::Plane(mydirection, myposition).projectVector(distance);
    124 
    125     float projectionlength = projection.length();
    126     if (projectionlength == 0) return orxonox::Vector2(0, 0);
    127     float angle = acos(clamp<float>(myorthonormal.dotProduct(projection) / projectionlength, -1, 1));
    128 
    129     if ((mydirection.crossProduct(myorthonormal)).dotProduct(distance) > 0)
    130         return orxonox::Vector2(sin(angle), cos(angle));
    131     else
    132         return orxonox::Vector2(-sin(angle), cos(angle));
    133 }
    134 
    135 /**
    136     @brief Gets the 2D viewing direction (up/down, left/right) to the position of the other object, multiplied with the viewing distance to the object (0° = 0, 180° = 1).
    137     @param myposition My position
    138     @param mydirection My viewing direction
    139     @param myorthonormal My orthonormalvector (pointing upwards through my head)
    140     @param otherposition The position of the other object
    141     @return The viewing direction
    142 
    143     @example
    144     If the other object is exactly in front of me, the function returns Vector2(0, 0).
    145     If the other object is exactly at my left, the function returns Vector2(-0.5, 0).
    146     If the other object is exactly at my right, the function returns Vector2(0.5, 0).
    147     If the other object is only a bit at my right, the function still returns Vector2(0.01, 0).
    148     If the other object is exactly above me, the function returns Vector2(0, 0.5).
    149 */
    150 orxonox::Vector2 get2DViewcoordinates(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition)
    151 {
    152     orxonox::Vector3 distance = otherposition - myposition;
    153 
    154     // project difference vector on our plane
    155     orxonox::Vector3 projection = Ogre::Plane(mydirection, myposition).projectVector(distance);
    156 
    157     float projectionlength = projection.length();
    158     if (projectionlength == 0) return orxonox::Vector2(0, 0);
    159     float angle = acos(clamp<float>(myorthonormal.dotProduct(projection) / projectionlength, -1, 1));
    160 
    161     float distancelength = distance.length();
    162     if (distancelength == 0) return orxonox::Vector2(0, 0);
    163     float radius = acos(clamp<float>(mydirection.dotProduct(distance) / distancelength, -1, 1)) / Ogre::Math::PI;
    164 
    165     if ((mydirection.crossProduct(myorthonormal)).dotProduct(distance) > 0)
    166         return orxonox::Vector2(sin(angle) * radius, cos(angle) * radius);
    167     else
    168         return orxonox::Vector2(-sin(angle) * radius, cos(angle) * radius);
    169 }
    170 
    171 /**
    172     @brief Returns the predicted position I have to aim at, if I want to hit a moving target with a moving projectile.
    173     @param myposition My position
    174     @param projectilespeed The speed of my projectile
    175     @param targetposition The position of my target
    176     @param targetvelocity The velocity of my target
    177     @return The predicted position
    178 
    179     The function predicts the position based on a linear velocity of the target. If the target changes speed or direction, the projectile will miss.
    180 */
    181 orxonox::Vector3 getPredictedPosition(const orxonox::Vector3& myposition, float projectilespeed, const orxonox::Vector3& targetposition, const orxonox::Vector3& targetvelocity)
    182 {
    183     float squaredProjectilespeed = projectilespeed * projectilespeed;
    184     orxonox::Vector3 distance = targetposition - myposition;
    185     float a = distance.squaredLength();
    186     float b = 2 * (distance.x + distance.y + distance.z) * (targetvelocity.x + targetvelocity.y + targetvelocity.z);
    187     float c = targetvelocity.squaredLength();
    188 
    189     float temp = 4*squaredProjectilespeed*c + a*a - 4*b*c;
    190     if (temp < 0)
    191         return orxonox::Vector3::ZERO;
    192 
    193     temp = sqrt(temp);
    194     float time = (temp + a) / (2 * (squaredProjectilespeed - b));
    195     return (targetposition + targetvelocity * time);
    196 }
    197 
    198 unsigned long getUniqueNumber()
    199 {
    200     static unsigned long aNumber = 135;
    201     return aNumber++;
    202 }
    203 
    204 
    205 //////////////////////////
    206 // Conversion functions //
    207 //////////////////////////
    208 
    209 // std::string to Vector2
    210 bool ConverterFallback<std::string, orxonox::Vector2>::convert(orxonox::Vector2* output, const std::string& input)
    211 {
    212     size_t opening_parenthesis, closing_parenthesis = input.find(')');
    213     if ((opening_parenthesis = input.find('(')) == std::string::npos)
    214         opening_parenthesis = 0;
    215     else
    216         opening_parenthesis++;
    217 
    218     SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis),
    219                      ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');
    220     if (tokens.size() >= 2)
    221     {
    222         if (!ConvertValue(&(output->x), tokens[0]))
    223             return false;
    224         if (!ConvertValue(&(output->y), tokens[1]))
    225             return false;
    226 
    227         return true;
    228     }
    229     return false;
    230 }
    231 
    232 // std::string to Vector3
    233 bool ConverterFallback<std::string, orxonox::Vector3>::convert(orxonox::Vector3* output, const std::string& input)
    234 {
    235     size_t opening_parenthesis, closing_parenthesis = input.find(')');
    236     if ((opening_parenthesis = input.find('(')) == std::string::npos)
    237         opening_parenthesis = 0;
    238     else
    239         opening_parenthesis++;
    240 
    241     SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis),
    242                      ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');
    243     if (tokens.size() >= 3)
    244     {
    245         if (!ConvertValue(&(output->x), tokens[0]))
    246             return false;
    247         if (!ConvertValue(&(output->y), tokens[1]))
    248             return false;
    249         if (!ConvertValue(&(output->z), tokens[2]))
    250             return false;
    251 
    252         return true;
    253     }
    254     return false;
    255 }
    256 
    257 // std::string to Vector4
    258 bool ConverterFallback<std::string, orxonox::Vector4>::convert(orxonox::Vector4* output, const std::string& input)
    259 {
    260     size_t opening_parenthesis, closing_parenthesis = input.find(')');
    261     if ((opening_parenthesis = input.find('(')) == std::string::npos)
    262         opening_parenthesis = 0;
    263     else
    264         opening_parenthesis++;
    265 
    266     SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis),
    267                      ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');
    268     if (tokens.size() >= 4)
    269     {
    270         if (!ConvertValue(&(output->x), tokens[0]))
    271             return false;
    272         if (!ConvertValue(&(output->y), tokens[1]))
    273             return false;
    274         if (!ConvertValue(&(output->z), tokens[2]))
    275             return false;
    276         if (!ConvertValue(&(output->w), tokens[3]))
    277             return false;
    278 
    279         return true;
    280     }
    281     return false;
    282 }
    283 
    284 // std::string to Quaternion
    285 bool ConverterFallback<std::string, orxonox::Quaternion>::convert(orxonox::Quaternion* output, const std::string& input)
    286 {
    287     size_t opening_parenthesis, closing_parenthesis = input.find(')');
    288     if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; }
    289 
    290     SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');
    291     if (tokens.size() >= 4)
    292     {
    293         if (!ConvertValue(&(output->w), tokens[0]))
    294             return false;
    295         if (!ConvertValue(&(output->x), tokens[1]))
    296             return false;
    297         if (!ConvertValue(&(output->y), tokens[2]))
    298             return false;
    299         if (!ConvertValue(&(output->z), tokens[3]))
    300             return false;
    301 
    302         return true;
    303     }
    304     return false;
    305 }
    306 
    307 // std::string to ColourValue
    308 bool ConverterFallback<std::string, orxonox::ColourValue>::convert(orxonox::ColourValue* output, const std::string& input)
    309 {
    310     size_t opening_parenthesis, closing_parenthesis = input.find(')');
    311     if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; }
    312 
    313     SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');
    314     if (tokens.size() >= 3)
    315     {
    316         if (!ConvertValue(&(output->r), tokens[0]))
    317             return false;
    318         if (!ConvertValue(&(output->g), tokens[1]))
    319             return false;
    320         if (!ConvertValue(&(output->b), tokens[2]))
    321             return false;
    322         if (tokens.size() >= 4)
    323         {
    324             if (!ConvertValue(&(output->a), tokens[3]))
    325                 return false;
    326         }
    327         else
    328             output->a = 1.0;
    329 
    330         return true;
    331     }
    332     return false;
    333 }
Note: See TracChangeset for help on using the changeset viewer.