108 lines
2.9 KiB
C++
108 lines
2.9 KiB
C++
#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<osg::Geometry> 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);
|
|
}
|