DYTSrouce/src/scene/SphereSegment.cpp
2025-01-04 12:12:51 +08:00

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);
}