]> git.mxchange.org Git - simgear.git/blob - simgear/scene/sky/sphere.cxx
Merge branch 'ehofman/sound'
[simgear.git] / simgear / scene / sky / sphere.cxx
1 // sphere.cxx -- build an ssg sphere object
2 //
3 // Pulled straight out of MesaGLU/quadratic.c
4 //
5 // Original gluSphere code is Copyright (C) 1999-2000  Brian Paul and
6 // licensed under the GPL
7 //
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.
12 //
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.
17 //
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.
21 //
22 // $Id$
23 #ifdef __CYGWIN__
24 #include <ieeefp.h>
25 #endif
26
27
28 #include <simgear/compiler.h>
29 #include <simgear/constants.h>
30 #include <simgear/debug/logstream.hxx>
31
32 #include <iostream>
33
34 #include <osg/Node>
35 #include <osg/Geometry>
36 #include <osg/Geode>
37 #include <osg/Array>
38
39
40 // return a sphere object as an ssgBranch
41 osg::Node*
42 SGMakeSphere(double radius, int slices, int stacks)
43 {
44     float rho, drho, dtheta;
45     float s, t, ds, dt;
46     int i, j, imin, imax;
47     float nsign = 1.0;
48     osg::Geode* geode = new osg::Geode;
49
50     drho = SGD_PI / (float) stacks;
51     dtheta = SGD_2PI / (float) slices;
52
53     /* texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y
54        axis t goes from -1.0/+1.0 at z = -radius/+radius (linear along
55        longitudes) cannot use triangle fan on texturing (s coord. at
56        top/bottom tip varies) */
57
58     ds = 1.0 / slices;
59     dt = 1.0 / stacks;
60     t = 1.0;  /* because loop now runs from 0 */
61     imin = 0;
62     imax = stacks;
63
64     /* build slices as quad strips */
65     for ( i = imin; i < imax; i++ ) {
66         osg::Geometry* geometry = new osg::Geometry;
67         osg::Vec3Array* vl = new osg::Vec3Array;
68         osg::Vec3Array* nl = new osg::Vec3Array;
69         osg::Vec2Array* tl = new osg::Vec2Array;
70
71         rho = i * drho;
72         s = 0.0;
73         for ( j = 0; j <= slices; j++ ) {
74             double theta = (j == slices) ? 0.0 : j * dtheta;
75             double x = -sin(theta) * sin(rho);
76             double y = cos(theta) * sin(rho);
77             double z = nsign * cos(rho);
78
79             // glNormal3f( x*nsign, y*nsign, z*nsign );
80             osg::Vec3 normal(x*nsign, y*nsign, z*nsign);
81             normal.normalize();
82             nl->push_back(normal);
83
84             // glTexCoord2f(s,t);
85             tl->push_back(osg::Vec2(s, t));
86
87             // glVertex3f( x*radius, y*radius, z*radius );
88             vl->push_back(osg::Vec3(x*radius, y*radius, z*radius));
89
90             x = -sin(theta) * sin(rho+drho);
91             y = cos(theta) * sin(rho+drho);
92             z = nsign * cos(rho+drho);
93
94             // glNormal3f( x*nsign, y*nsign, z*nsign );
95             normal = osg::Vec3(x*nsign, y*nsign, z*nsign);
96             normal.normalize();
97             nl->push_back(normal);
98
99             // glTexCoord2f(s,t-dt);
100             tl->push_back(osg::Vec2(s, t-dt));
101             s += ds;
102
103             // glVertex3f( x*radius, y*radius, z*radius );
104             vl->push_back(osg::Vec3(x*radius, y*radius, z*radius));
105         }
106
107         if ( vl->size() != nl->size() ) {
108             SG_LOG( SG_EVENT, SG_ALERT, "bad sphere1");
109             exit(-1);
110         }
111         if ( vl->size() != tl->size() ) {
112             SG_LOG( SG_EVENT, SG_ALERT, "bad sphere2");
113             exit(-1);
114         }
115
116         // colors
117         osg::Vec4Array* cl = new osg::Vec4Array;
118         cl->push_back(osg::Vec4(1, 1, 1, 1));
119
120         geometry->setUseDisplayList(false);
121         geometry->setVertexArray(vl);
122         geometry->setNormalArray(nl);
123         geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
124         geometry->setTexCoordArray(0, tl);
125         geometry->setColorArray(cl);
126         geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
127         geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, vl->size()));
128         geode->addDrawable(geometry);
129
130         t -= dt;
131     }
132
133     return geode;
134 }