Introduce osg::asciiToDouble/asciiToFloat function.

This commit is contained in:
Robert Osfield 2008-11-23 11:35:43 +00:00
parent d946a6536e
commit 8264b31fa1
5 changed files with 145 additions and 118 deletions

View File

@ -16,6 +16,8 @@
#include <math.h>
#include <osg/Export>
//certain math functions were not defined until 10.2
//so this code checks the version so it can add in workarounds for older versions.
#ifdef __APPLE__
@ -226,6 +228,12 @@ inline float computeVolume(const T& f1,const T& f2,const T& f3,
computeVolume(b1,b3,f2,f3);
}
/** Convert a ascii number to a double, ignoring locale settings.*/
extern OSG_EXPORT double asciiToDouble(const char* str);
/** Convert a ascii number to a float, ignoring locale settings.*/
inline float asciiToFloat(const char* str) { return static_cast<float>(asciiToDouble(str)); }
}
#endif // __OSG_MATH

View File

@ -21,7 +21,6 @@
namespace osgDB {
class OSGDB_EXPORT Field
{
public:

View File

@ -216,24 +216,26 @@ ADD_LIBRARY(${LIB_NAME}
CoordinateSystemNode.cpp
CopyOp.cpp
CullFace.cpp
CullingSet.cpp
CullSettings.cpp
CullStack.cpp
CullingSet.cpp
DeleteHandler.cpp
Depth.cpp
DisplaySettings.cpp
DrawPixels.cpp
Drawable.cpp
DrawPixels.cpp
dxtctool.cpp
dxtctool.h
Fog.cpp
FragmentProgram.cpp
FrameBufferObject.cpp
FrameStamp.cpp
FrontFace.cpp
Geode.cpp
Geometry.cpp
GL2Extensions.cpp
GLExtensions.cpp
GLObjects.cpp
Geode.cpp
Geometry.cpp
GraphicsContext.cpp
GraphicsThread.cpp
Group.cpp
@ -242,24 +244,25 @@ ADD_LIBRARY(${LIB_NAME}
ImageSequence.cpp
ImageStream.cpp
KdTree.cpp
LOD.cpp
Light.cpp
LightModel.cpp
LightSource.cpp
LineSegment.cpp
LineStipple.cpp
LineWidth.cpp
LOD.cpp
LogicOp.cpp
Material.cpp
Math.cpp
Matrixd.cpp
MatrixDecomposition.cpp
MatrixTransform.cpp
Matrixf.cpp
# We don't build this one
# Matrix_implementation.cpp
Matrixd.cpp
Matrixf.cpp
MatrixTransform.cpp
Multisample.cpp
Node.cpp
NodeCallback.cpp
Node.cpp
NodeTrackerCallback.cpp
NodeVisitor.cpp
Notify.cpp
@ -287,36 +290,34 @@ ADD_LIBRARY(${LIB_NAME}
ShadowVolumeOccluder.cpp
Shape.cpp
ShapeDrawable.cpp
State.cpp
StateAttribute.cpp
State.cpp
StateSet.cpp
Stats.cpp
Stencil.cpp
StencilTwoSided.cpp
Switch.cpp
TexEnv.cpp
TexEnvCombine.cpp
TexEnv.cpp
TexEnvFilter.cpp
TexGen.cpp
TexGenNode.cpp
TexMat.cpp
Texture.cpp
Texture1D.cpp
Texture2D.cpp
Texture2DArray.cpp
Texture2D.cpp
Texture3D.cpp
Texture.cpp
TextureCubeMap.cpp
TextureRectangle.cpp
TransferFunction.cpp
Timer.cpp
TransferFunction.cpp
Transform.cpp
Uniform.cpp
Version.cpp
VertexProgram.cpp
View.cpp
Viewport.cpp
dxtctool.cpp
dxtctool.h
)
LINK_INTERNAL(${LIB_NAME}

114
src/osg/Math.cpp Normal file
View File

@ -0,0 +1,114 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* 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
* OpenSceneGraph Public License for more details.
*/
#include <osg/Math>
#include <string.h>
double osg::asciiToDouble(const char* str)
{
const char* ptr = str;
// check if could be a hex number.
if (strncmp(ptr,"0x",2)==0)
{
double value = 0.0;
// skip over leading 0x, and then go through rest of string
// checking to make sure all values are 0...9 or a..f.
ptr+=2;
while (
*ptr!=0 &&
((*ptr>='0' && *ptr<='9') ||
(*ptr>='a' && *ptr<='f') ||
(*ptr>='A' && *ptr<='F'))
)
{
if (*ptr>='0' && *ptr<='9') value = value*16.0 + double(*ptr-'0');
else if (*ptr>='a' && *ptr<='f') value = value*16.0 + double(*ptr-'a'+10);
else if (*ptr>='A' && *ptr<='F') value = value*16.0 + double(*ptr-'A'+10);
++ptr;
}
// osg::notify(osg::NOTICE)<<"Read "<<str<<" result = "<<value<<std::endl;
return value;
}
ptr = str;
bool hadDecimal[2];
double value[2];
double sign[2];
double decimalMultiplier[2];
hadDecimal[0] = hadDecimal[1] = false;
sign[0] = sign[1] = 1.0;
value[0] = value[1] = 0.0;
decimalMultiplier[0] = decimalMultiplier[1] = 0.1;
int pos = 0;
// compute mantissa and exponent parts
while (*ptr!=0 && pos<2)
{
if (*ptr=='+')
{
sign[pos] = 1.0;
}
else if (*ptr=='-')
{
sign[pos] = -1.0;
}
else if (*ptr>='0' && *ptr<='9')
{
if (!hadDecimal[pos])
{
value[pos] = value[pos]*10.0 + double(*ptr-'0');
}
else
{
value[pos] = value[pos] + decimalMultiplier[pos] * double(*ptr-'0');
decimalMultiplier[pos] *= 0.1;
}
}
else if (*ptr=='.')
{
hadDecimal[pos] = true;
}
else if (*ptr=='e' || *ptr=='E')
{
if (pos==1) break;
pos = 1;
}
else
{
break;
}
++ptr;
}
if (pos==0)
{
// osg::notify(osg::NOTICE)<<"Read "<<str<<" result = "<<value[0]*sign[0]<<std::endl;
return value[0]*sign[0];
}
else
{
double mantissa = value[0]*sign[0];
double exponent = value[1]*sign[1];
//osg::notify(osg::NOTICE)<<"Read "<<str<<" mantissa = "<<mantissa<<" exponent="<<exponent<<" result = "<<mantissa*pow(10.0,exponent)<<std::endl;
return mantissa*pow(10.0,exponent);
}
}

View File

@ -11,111 +11,16 @@
* OpenSceneGraph Public License for more details.
*/
#include <string.h>
#include <math.h>
#include <osg/Notify>
#include <osg/Math>
#include <osgDB/Field>
using namespace osgDB;
using namespace std;
double osg_atof(const char* str)
{
const char* ptr = str;
// check if could be a hex number.
if (strncmp(ptr,"0x",2)==0)
{
double value = 0.0;
// skip over leading 0x, and then go through rest of string
// checking to make sure all values are 0...9 or a..f.
ptr+=2;
while (
*ptr!=0 &&
((*ptr>='0' && *ptr<='9') ||
(*ptr>='a' && *ptr<='f') ||
(*ptr>='A' && *ptr<='F'))
)
{
if (*ptr>='0' && *ptr<='9') value = value*16.0 + double(*ptr-'0');
else if (*ptr>='a' && *ptr<='f') value = value*16.0 + double(*ptr-'a'+10);
else if (*ptr>='A' && *ptr<='F') value = value*16.0 + double(*ptr-'A'+10);
++ptr;
}
// osg::notify(osg::NOTICE)<<"Read "<<str<<" result = "<<value<<std::endl;
return value;
}
ptr = str;
bool hadDecimal[2];
double value[2];
double sign[2];
double decimalMultiplier[2];
hadDecimal[0] = hadDecimal[1] = false;
sign[0] = sign[1] = 1.0;
value[0] = value[1] = 0.0;
decimalMultiplier[0] = decimalMultiplier[1] = 0.1;
int pos = 0;
// compute mantissa and exponent parts
while (*ptr!=0 && pos<2)
{
if (*ptr=='+')
{
sign[pos] = 1.0;
}
else if (*ptr=='-')
{
sign[pos] = -1.0;
}
else if (*ptr>='0' && *ptr<='9')
{
if (!hadDecimal[pos])
{
value[pos] = value[pos]*10.0 + double(*ptr-'0');
}
else
{
value[pos] = value[pos] + decimalMultiplier[pos] * double(*ptr-'0');
decimalMultiplier[pos] *= 0.1;
}
}
else if (*ptr=='.')
{
hadDecimal[pos] = true;
}
else if (*ptr=='e' || *ptr=='E')
{
if (pos==1) break;
pos = 1;
}
else
{
break;
}
++ptr;
}
if (pos==0)
{
// osg::notify(osg::NOTICE)<<"Read "<<str<<" result = "<<value[0]*sign[0]<<std::endl;
return value[0]*sign[0];
}
else
{
double mantissa = value[0]*sign[0];
double exponent = value[1]*sign[1];
//osg::notify(osg::NOTICE)<<"Read "<<str<<" mantissa = "<<mantissa<<" exponent="<<exponent<<" result = "<<mantissa*pow(10.0,exponent)<<std::endl;
return mantissa*pow(10.0,exponent);
}
}
Field::Field()
{
_init();
@ -438,7 +343,7 @@ bool Field::matchFloat(float f) const
getFieldType();
if (_fieldType==REAL || _fieldType==INTEGER)
{
return (float)osg_atof(_fieldCache)==f;
return osg::asciiToFloat(_fieldCache)==f;
}
else
{
@ -452,7 +357,7 @@ bool Field::getFloat(float& f) const
getFieldType();
if (_fieldType==REAL || _fieldType==INTEGER)
{
f = (float)osg_atof(_fieldCache);
f = osg::asciiToFloat(_fieldCache);
return true;
}
else
@ -466,7 +371,7 @@ bool Field::getFloat(double& f) const
getFieldType();
if (_fieldType==REAL || _fieldType==INTEGER)
{
f = osg_atof(_fieldCache);
f = osg::asciiToDouble(_fieldCache);
return true;
}
else