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 <math.h>
#include <osg/Export>
//certain math functions were not defined until 10.2 //certain math functions were not defined until 10.2
//so this code checks the version so it can add in workarounds for older versions. //so this code checks the version so it can add in workarounds for older versions.
#ifdef __APPLE__ #ifdef __APPLE__
@ -226,6 +228,12 @@ inline float computeVolume(const T& f1,const T& f2,const T& f3,
computeVolume(b1,b3,f2,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 #endif // __OSG_MATH

View File

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

View File

@ -216,24 +216,26 @@ ADD_LIBRARY(${LIB_NAME}
CoordinateSystemNode.cpp CoordinateSystemNode.cpp
CopyOp.cpp CopyOp.cpp
CullFace.cpp CullFace.cpp
CullingSet.cpp
CullSettings.cpp CullSettings.cpp
CullStack.cpp CullStack.cpp
CullingSet.cpp
DeleteHandler.cpp DeleteHandler.cpp
Depth.cpp Depth.cpp
DisplaySettings.cpp DisplaySettings.cpp
DrawPixels.cpp
Drawable.cpp Drawable.cpp
DrawPixels.cpp
dxtctool.cpp
dxtctool.h
Fog.cpp Fog.cpp
FragmentProgram.cpp FragmentProgram.cpp
FrameBufferObject.cpp FrameBufferObject.cpp
FrameStamp.cpp FrameStamp.cpp
FrontFace.cpp FrontFace.cpp
Geode.cpp
Geometry.cpp
GL2Extensions.cpp GL2Extensions.cpp
GLExtensions.cpp GLExtensions.cpp
GLObjects.cpp GLObjects.cpp
Geode.cpp
Geometry.cpp
GraphicsContext.cpp GraphicsContext.cpp
GraphicsThread.cpp GraphicsThread.cpp
Group.cpp Group.cpp
@ -242,24 +244,25 @@ ADD_LIBRARY(${LIB_NAME}
ImageSequence.cpp ImageSequence.cpp
ImageStream.cpp ImageStream.cpp
KdTree.cpp KdTree.cpp
LOD.cpp
Light.cpp Light.cpp
LightModel.cpp LightModel.cpp
LightSource.cpp LightSource.cpp
LineSegment.cpp LineSegment.cpp
LineStipple.cpp LineStipple.cpp
LineWidth.cpp LineWidth.cpp
LOD.cpp
LogicOp.cpp LogicOp.cpp
Material.cpp Material.cpp
Math.cpp
Matrixd.cpp
MatrixDecomposition.cpp MatrixDecomposition.cpp
MatrixTransform.cpp Matrixf.cpp
# We don't build this one # We don't build this one
# Matrix_implementation.cpp # Matrix_implementation.cpp
Matrixd.cpp MatrixTransform.cpp
Matrixf.cpp
Multisample.cpp Multisample.cpp
Node.cpp
NodeCallback.cpp NodeCallback.cpp
Node.cpp
NodeTrackerCallback.cpp NodeTrackerCallback.cpp
NodeVisitor.cpp NodeVisitor.cpp
Notify.cpp Notify.cpp
@ -287,36 +290,34 @@ ADD_LIBRARY(${LIB_NAME}
ShadowVolumeOccluder.cpp ShadowVolumeOccluder.cpp
Shape.cpp Shape.cpp
ShapeDrawable.cpp ShapeDrawable.cpp
State.cpp
StateAttribute.cpp StateAttribute.cpp
State.cpp
StateSet.cpp StateSet.cpp
Stats.cpp Stats.cpp
Stencil.cpp Stencil.cpp
StencilTwoSided.cpp StencilTwoSided.cpp
Switch.cpp Switch.cpp
TexEnv.cpp
TexEnvCombine.cpp TexEnvCombine.cpp
TexEnv.cpp
TexEnvFilter.cpp TexEnvFilter.cpp
TexGen.cpp TexGen.cpp
TexGenNode.cpp TexGenNode.cpp
TexMat.cpp TexMat.cpp
Texture.cpp
Texture1D.cpp Texture1D.cpp
Texture2D.cpp
Texture2DArray.cpp Texture2DArray.cpp
Texture2D.cpp
Texture3D.cpp Texture3D.cpp
Texture.cpp
TextureCubeMap.cpp TextureCubeMap.cpp
TextureRectangle.cpp TextureRectangle.cpp
TransferFunction.cpp
Timer.cpp Timer.cpp
TransferFunction.cpp
Transform.cpp Transform.cpp
Uniform.cpp Uniform.cpp
Version.cpp Version.cpp
VertexProgram.cpp VertexProgram.cpp
View.cpp View.cpp
Viewport.cpp Viewport.cpp
dxtctool.cpp
dxtctool.h
) )
LINK_INTERNAL(${LIB_NAME} 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. * OpenSceneGraph Public License for more details.
*/ */
#include <string.h> #include <string.h>
#include <math.h>
#include <osg/Notify> #include <osg/Notify>
#include <osg/Math>
#include <osgDB/Field> #include <osgDB/Field>
using namespace osgDB; using namespace osgDB;
using namespace std; 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() Field::Field()
{ {
_init(); _init();
@ -438,7 +343,7 @@ bool Field::matchFloat(float f) const
getFieldType(); getFieldType();
if (_fieldType==REAL || _fieldType==INTEGER) if (_fieldType==REAL || _fieldType==INTEGER)
{ {
return (float)osg_atof(_fieldCache)==f; return osg::asciiToFloat(_fieldCache)==f;
} }
else else
{ {
@ -452,7 +357,7 @@ bool Field::getFloat(float& f) const
getFieldType(); getFieldType();
if (_fieldType==REAL || _fieldType==INTEGER) if (_fieldType==REAL || _fieldType==INTEGER)
{ {
f = (float)osg_atof(_fieldCache); f = osg::asciiToFloat(_fieldCache);
return true; return true;
} }
else else
@ -466,7 +371,7 @@ bool Field::getFloat(double& f) const
getFieldType(); getFieldType();
if (_fieldType==REAL || _fieldType==INTEGER) if (_fieldType==REAL || _fieldType==INTEGER)
{ {
f = osg_atof(_fieldCache); f = osg::asciiToDouble(_fieldCache);
return true; return true;
} }
else else