//osg/ShapeDrawable.cpp
void DrawShapeVisitor::apply(const Sphere& sphere)
{
GLBeginEndAdapter& gl = _state.getGLBeginEndAdapter();
gl.PushMatrix();
gl.Translated(sphere.getCenter().x(),sphere.getCenter().y(),sphere.getCenter().z());
bool drawFrontFace = _hints ? _hints->getCreateFrontFace() : true;
bool drawBackFace = _hints ? _hints->getCreateBackFace() : false;
unsigned int numSegments = 40;
unsigned int numRows = 20;
float ratio = (_hints ? _hints->getDetailRatio() : 1.0f);
if (ratio > 0.0f && ratio != 1.0f) {
numRows = (unsigned int) (numRows * ratio);
if (numRows < MIN_NUM_ROWS)
numRows = MIN_NUM_ROWS;
numSegments = (unsigned int) (numSegments * ratio);
if (numSegments < MIN_NUM_SEGMENTS)
numSegments = MIN_NUM_SEGMENTS;
}
float lDelta = osg::PI/(float)numRows;
float vDelta = 1.0f/(float)numRows;
float angleDelta = osg::PI*2.0f/(float)numSegments;
float texCoordHorzDelta = 1.0f/(float)numSegments;
gl.Begin(GL_QUAD_STRIP);
if (drawBackFace)
{
float lBase=-osg::PI*0.5f;
float rBase=0.0f;
float zBase=-sphere.getRadius();
float vBase=0.0f;
float nzBase=-1.0f;
float nRatioBase=0.0f;
for(unsigned int rowi=0; rowi
{
float lTop = lBase+lDelta;
float rTop = cosf(lTop)*sphere.getRadius();
float zTop = sinf(lTop)*sphere.getRadius();
float vTop = vBase+vDelta;
float nzTop= sinf(lTop);
float nRatioTop= cosf(lTop);
gl.Begin(GL_QUAD_STRIP);
float angle = 0.0f;
for(unsigned int topi=0; topi
++topi,angle+=angleDelta,texCoord+=texCoordHorzDelta)
{
float c = cosf(angle);
float s = sinf(angle);
gl.Normal3f(-c*nRatioBase,-s*nRatioBase,-nzBase);
gl.TexCoord2f(texCoord,vBase);
gl.Vertex3f(c*rBase,s*rBase,zBase);
gl.Normal3f(-c*nRatioTop,-s*nRatioTop,-nzTop);
gl.TexCoord2f(texCoord,vTop);
gl.Vertex3f(c*rTop,s*rTop,zTop);
}
// do last point by hand to ensure no round off errors.
gl.Normal3f(-nRatioBase,0.0f,-nzBase);
gl.TexCoord2f(1.0f,vBase);
gl.Vertex3f(rBase,0.0f,zBase);
gl.Normal3f(-nRatioTop,0.0f,-nzTop);
gl.TexCoord2f(1.0f,vTop);
gl.Vertex3f(rTop,0.0f,zTop);
gl.End();
lBase=lTop;
rBase=rTop;
zBase=zTop;
vBase=vTop;
nzBase=nzTop;
nRatioBase=nRatioTop;
}
}
if (drawFrontFace)
{
float lBase=-osg::PI*0.5f;
float rBase=0.0f;
float zBase=-sphere.getRadius();
float vBase=0.0f;
float nzBase=-1.0f;
float nRatioBase=0.0f;
for(unsigned int rowi=0; rowi
{
float lTop = lBase+lDelta;
float rTop = cosf(lTop)*sphere.getRadius();
float zTop = sinf(lTop)*sphere.getRadius();
float vTop = vBase+vDelta;
float nzTop= sinf(lTop);
float nRatioTop= cosf(lTop);
gl.Begin(GL_QUAD_STRIP);
float angle = 0.0f;
float texCoord = 0.0f;
for(unsigned int topi=0; topi
++topi,angle+=angleDelta,texCoord+=texCoordHorzDelta)
{
float c = cosf(angle);
float s = sinf(angle);
gl.Normal3f(c*nRatioTop,s*nRatioTop,nzTop);
gl.TexCoord2f(texCoord,vTop);
gl.Vertex3f(c*rTop,s*rTop,zTop);
gl.Normal3f(c*nRatioBase,s*nRatioBase,nzBase);
gl.TexCoord2f(texCoord,vBase);
gl.Vertex3f(c*rBase,s*rBase,zBase);
}
// do last point by hand to ensure no round off errors.
gl.Normal3f(nRatioTop,0.0f,nzTop);
gl.TexCoord2f(1.0f,vTop);
gl.Vertex3f(rTop,0.0f,zTop);
gl.Normal3f(nRatioBase,0.0f,nzBase);
gl.TexCoord2f(1.0f,vBase);
gl.Vertex3f(rBase,0.0f,zBase);
gl.End();
lBase=lTop;
rBase=rTop;
zBase=zTop;
vBase=vTop;
nzBase=nzTop;
nRatioBase=nRatioTop;
}
}
gl.PopMatrix();
}