SphereSegment.cpp
Go to the documentation of this file.
00001 /*
00002  * This source file is part of the osgOcean library
00003  *
00004  * Copyright (C) 2009 Kim Bale
00005  * Copyright (C) 2009 The University of Hull, UK
00006  *
00007  * This program is free software; you can redistribute it and/or modify it under
00008  * the terms of the GNU Lesser General Public License as published by the Free Software
00009  * Foundation; either version 3 of the License, or (at your option) any later
00010  * version.
00011 
00012  * This program is distributed in the hope that it will be useful, but WITHOUT
00013  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00014  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
00015  * http://www.gnu.org/copyleft/lesser.txt.
00016  */
00017 
00018 #include <uwsim/SphereSegment.h>
00019 
00020 SphereSegment::SphereSegment(void)
00021 {
00022 }
00023 
00024 SphereSegment::SphereSegment(float radius, unsigned int longitudeSteps, unsigned int lattitudeSteps, float longStart,
00025                              float longEnd, float latStart, float latEnd)
00026 {
00027   compute(radius, longitudeSteps, lattitudeSteps, longStart, longEnd, latStart, latEnd);
00028 }
00029 
00030 SphereSegment::SphereSegment(const SphereSegment& copy, const osg::CopyOp& copyop) :
00031     osg::Geode(copy, copyop)
00032 {
00033 }
00034 
00035 SphereSegment::~SphereSegment(void)
00036 {
00037 }
00038 
00039 // 0 >= longStart/longEnd <= 180
00040 // 0 >= latStart/latEnd <= 360
00041 
00042 void SphereSegment::compute(float radius, unsigned int longitudeSteps, unsigned int lattitudeSteps, float longStart,
00043                             float longEnd, float latStart, float latEnd)
00044 
00045 {
00046   removeDrawables(0, getNumDrawables());
00047 
00048   osg::Vec3Array* vertices = new osg::Vec3Array();
00049   osg::Vec2Array* texcoords = new osg::Vec2Array();
00050 
00051   double x, y, z, t, p, sin_t, cos_t;
00052 
00053   double longInc = (longEnd - longStart) / (double)longitudeSteps;
00054   double latInc = (latEnd - latStart) / (double)lattitudeSteps;
00055 
00056   double theta = longStart, phi = latStart;
00057 
00058   float uScale = 1.f / longitudeSteps;
00059   float vScale = 1.f / lattitudeSteps;
00060 
00061   for (unsigned int i = 0; i <= longitudeSteps; ++i)
00062   {
00063     t = osg::DegreesToRadians(theta);
00064     sin_t = sin(t);
00065     cos_t = cos(t);
00066 
00067     for (unsigned int j = 0; j <= lattitudeSteps; ++j)
00068     {
00069       p = osg::DegreesToRadians(phi);
00070 
00071       x = radius * sin_t * cos(p);
00072       y = radius * sin_t * sin(p);
00073       z = radius * cos_t;
00074 
00075       vertices->push_back(osg::Vec3(x, y, z));
00076       texcoords->push_back(osg::Vec2(j * vScale, i * uScale));
00077 
00078       phi += latInc;
00079     }
00080 
00081     theta -= longInc;
00082     phi = latStart;
00083   }
00084 
00085   osg::ref_ptr < osg::Geometry > geom = new osg::Geometry();
00086 
00087   for (unsigned int r = 0; r <= longitudeSteps - 1; r += 1)
00088   {
00089     osg::DrawElementsUInt* indices = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLE_STRIP, 0);
00090 
00091     for (unsigned int c = 0; c <= lattitudeSteps; c += 1)
00092     {
00093       indices->push_back(idx(r, c, lattitudeSteps + 1));
00094       indices->push_back(idx(r + 1, c, lattitudeSteps + 1));
00095     }
00096 
00097     geom->addPrimitiveSet(indices);
00098   }
00099 
00100   osg::Vec4Array* colors = new osg::Vec4Array();
00101   colors->push_back(osg::Vec4(1.f, 1.f, 1.f, 1.f));
00102 
00103   geom->setVertexArray(vertices);
00104   geom->setTexCoordArray(0, texcoords);
00105   geom->setColorArray(colors);
00106   geom->setColorBinding(osg::Geometry::BIND_OVERALL);
00107 
00108   addDrawable(geom.get());
00109 }
00110 
00111 osg::Vec2 SphereSegment::sphereMap(osg::Vec3& vertex, float radius)
00112 {
00113   float u, v;
00114 
00115   float TWOPI = osg::PI * 2.f;
00116 
00117   v = acos(vertex.y() / radius) / osg::PI;
00118 
00119   if (vertex.z() >= 0.f)
00120     u = acos(vertex.x() / (radius * sin(osg::PI * v))) / TWOPI;
00121   else
00122     u = (osg::PI + acos(vertex.x() / (radius * sin(osg::PI * v)))) / TWOPI;
00123 
00124   return osg::Vec2(u, v);
00125 }


uwsim
Author(s): Mario Prats
autogenerated on Mon Oct 6 2014 08:24:07