1 // sphere.cxx -- build an ssg sphere object
3 // Pulled straight out of MesaGLU/quadratic.c
5 // Original gluSphere code is Copyright (C) 1999-2000 Brian Paul and
6 // licensed under the GPL
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Library General Public
10 // License as published by the Free Software Foundation; either
11 // version 2 of the License, or (at your option) any later version.
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Library General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 #include <simgear/compiler.h>
25 #include <simgear/constants.h>
26 #include <simgear/debug/logstream.hxx>
31 #include <osg/Geometry>
36 // return a sphere object as an ssgBranch
38 SGMakeSphere(double radius, int slices, int stacks)
40 float rho, drho, dtheta;
44 osg::Geode* geode = new osg::Geode;
46 drho = SGD_PI / (float) stacks;
47 dtheta = SGD_2PI / (float) slices;
49 /* texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y
50 axis t goes from -1.0/+1.0 at z = -radius/+radius (linear along
51 longitudes) cannot use triangle fan on texturing (s coord. at
52 top/bottom tip varies) */
56 t = 1.0; /* because loop now runs from 0 */
60 /* build slices as quad strips */
61 for ( i = imin; i < imax; i++ ) {
62 osg::Geometry* geometry = new osg::Geometry;
63 osg::Vec3Array* vl = new osg::Vec3Array;
64 osg::Vec3Array* nl = new osg::Vec3Array;
65 osg::Vec2Array* tl = new osg::Vec2Array;
69 for ( j = 0; j <= slices; j++ ) {
70 double theta = (j == slices) ? 0.0 : j * dtheta;
71 double x = -sin(theta) * sin(rho);
72 double y = cos(theta) * sin(rho);
73 double z = nsign * cos(rho);
75 // glNormal3f( x*nsign, y*nsign, z*nsign );
76 osg::Vec3 normal(x*nsign, y*nsign, z*nsign);
78 nl->push_back(normal);
81 tl->push_back(osg::Vec2(s, t));
83 // glVertex3f( x*radius, y*radius, z*radius );
84 vl->push_back(osg::Vec3(x*radius, y*radius, z*radius));
86 x = -sin(theta) * sin(rho+drho);
87 y = cos(theta) * sin(rho+drho);
88 z = nsign * cos(rho+drho);
90 // glNormal3f( x*nsign, y*nsign, z*nsign );
91 normal = osg::Vec3(x*nsign, y*nsign, z*nsign);
93 nl->push_back(normal);
95 // glTexCoord2f(s,t-dt);
96 tl->push_back(osg::Vec2(s, t-dt));
99 // glVertex3f( x*radius, y*radius, z*radius );
100 vl->push_back(osg::Vec3(x*radius, y*radius, z*radius));
103 if ( vl->size() != nl->size() ) {
104 SG_LOG( SG_EVENT, SG_ALERT, "bad sphere1");
107 if ( vl->size() != tl->size() ) {
108 SG_LOG( SG_EVENT, SG_ALERT, "bad sphere2");
113 osg::Vec4Array* cl = new osg::Vec4Array;
114 cl->push_back(osg::Vec4(1, 1, 1, 1));
116 geometry->setUseDisplayList(false);
117 geometry->setVertexArray(vl);
118 geometry->setNormalArray(nl);
119 geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
120 geometry->setTexCoordArray(0, tl);
121 geometry->setColorArray(cl);
122 geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
123 geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, vl->size()));
124 geode->addDrawable(geometry);