#include "scene/SphereSegment.h" SphereSegment::SphereSegment(void) {} SphereSegment::SphereSegment(float radius, unsigned int longitudeSteps, unsigned int lattitudeSteps, float longStart, float longEnd, float latStart, float latEnd) { Compute(radius, longitudeSteps, lattitudeSteps, longStart, longEnd, latStart, latEnd); } SphereSegment::SphereSegment(const SphereSegment& copy, const osg::CopyOp& copyop) : osg::Geode(copy, copyop) {} SphereSegment::~SphereSegment(void) {} // 0 >= longStart/longEnd <= 180 // 0 >= latStart/latEnd <= 360 void SphereSegment::Compute(float radius, unsigned int longitudeSteps, unsigned int lattitudeSteps, float longStart, float longEnd, float latStart, float latEnd) { removeDrawables(0, getNumDrawables()); osg::Vec3Array* vertices = new osg::Vec3Array(); osg::Vec2Array* texcoords = new osg::Vec2Array(); double x, y, z, t, p, sin_t, cos_t; double longInc = (longEnd - longStart) / (double)longitudeSteps; double latInc = (latEnd - latStart) / (double)lattitudeSteps; double theta = longStart, phi = latStart; float uScale = 1.f / longitudeSteps; float vScale = 1.f / lattitudeSteps; for (unsigned int i = 0; i <= longitudeSteps; ++i) { t = osg::DegreesToRadians(theta); sin_t = sin(t); cos_t = cos(t); for (unsigned int j = 0; j <= lattitudeSteps; ++j) { p = osg::DegreesToRadians(phi); x = radius * sin_t * cos(p); y = radius * sin_t * sin(p); z = radius * cos_t; vertices->push_back(osg::Vec3(x, y, z)); texcoords->push_back(osg::Vec2(j * vScale, i * uScale)); phi += latInc; } theta -= longInc; phi = latStart; } osg::ref_ptr geom = new osg::Geometry(); for (unsigned int r = 0; r <= longitudeSteps - 1; r += 1) { osg::DrawElementsUInt* indices = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLE_STRIP, 0); for (unsigned int c = 0; c <= lattitudeSteps; c += 1) { indices->push_back(Idx(r, c, lattitudeSteps + 1)); indices->push_back(Idx(r + 1, c, lattitudeSteps + 1)); } geom->addPrimitiveSet(indices); } osg::Vec4Array* colors = new osg::Vec4Array(); colors->push_back(osg::Vec4(1.f, 1.f, 1.f, 1.f)); geom->setVertexArray(vertices); geom->setTexCoordArray(0, texcoords); geom->setColorArray(colors); geom->setColorBinding(osg::Geometry::BIND_OVERALL); addDrawable(geom.get()); } osg::Vec2 SphereSegment::SphereMap(osg::Vec3& vertex, float radius) { float u, v; float TWOPI = osg::PI * 2.f; v = acos(vertex.y() / radius) / osg::PI; if (vertex.z() >= 0.f) u = acos(vertex.x() / (radius * sin(osg::PI * v))) / TWOPI; else u = (osg::PI + acos(vertex.x() / (radius * sin(osg::PI * v)))) / TWOPI; return osg::Vec2(u, v); }