]> git.mxchange.org Git - simgear.git/blob - simgear/sky/sphere.cxx
Collapsed the init() method into the constructor.
[simgear.git] / simgear / 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 program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License as
10 // published by the Free Software Foundation; either version 2 of the
11 // License, or (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful, but
14 // WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 // 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., 675 Mass Ave, Cambridge, MA 02139, USA.
21 //
22 // $Id$
23
24
25 #ifdef HAVE_CONFIG_H
26 #  include <config.h>
27 #endif
28
29 #include <simgear/compiler.h>
30
31 #include STL_IOSTREAM
32
33 #include <plib/sg.h>
34 #include <plib/ssg.h>
35
36
37 // return a sphere object as an ssgBranch
38 ssgBranch *ssgMakeSphere( ssgSimpleState *state, ssgColourArray *cl,
39                           double radius, int slices, int stacks,
40                           ssgCallback predraw, ssgCallback postdraw )
41 {
42     float rho, drho, theta, dtheta;
43     float x, y, z;
44     float s, t, ds, dt;
45     int i, j, imin, imax;
46     float nsign = 1.0;
47     ssgBranch *sphere = new ssgBranch;
48     sgVec2 vec2;
49     sgVec3 vec3;
50
51     drho = SG_PI / (float) stacks;
52     dtheta = 2.0 * SG_PI / (float) slices;
53
54     /* texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y
55        axis t goes from -1.0/+1.0 at z = -radius/+radius (linear along
56        longitudes) cannot use triangle fan on texturing (s coord. at
57        top/bottom tip varies) */
58
59     ds = 1.0 / slices;
60     dt = 1.0 / stacks;
61     t = 1.0;  /* because loop now runs from 0 */
62     imin = 0;
63     imax = stacks;
64
65     /* build slices as quad strips */
66     for ( i = imin; i < imax; i++ ) {
67         ssgVertexArray   *vl = new ssgVertexArray();
68         ssgNormalArray   *nl = new ssgNormalArray();
69         ssgTexCoordArray *tl = new ssgTexCoordArray();
70
71         rho = i * drho;
72         s = 0.0;
73         for ( j = 0; j <= slices; j++ ) {
74             theta = (j == slices) ? 0.0 : j * dtheta;
75             x = -sin(theta) * sin(rho);
76             y = cos(theta) * sin(rho);
77             z = nsign * cos(rho);
78
79             // glNormal3f( x*nsign, y*nsign, z*nsign );
80             sgSetVec3( vec3, x*nsign, y*nsign, z*nsign );
81             sgNormalizeVec3( vec3 );
82             nl->add( vec3 );
83
84             // glTexCoord2f(s,t);
85             sgSetVec2( vec2, s, t );
86             tl->add( vec2 );
87
88             // glVertex3f( x*radius, y*radius, z*radius );
89             sgSetVec3( vec3, x*radius, y*radius, z*radius );
90             vl->add( vec3 );
91
92             x = -sin(theta) * sin(rho+drho);
93             y = cos(theta) * sin(rho+drho);
94             z = nsign * cos(rho+drho);
95
96             // glNormal3f( x*nsign, y*nsign, z*nsign );
97             sgSetVec3( vec3, x*nsign, y*nsign, z*nsign );
98             sgNormalizeVec3( vec3 );
99             nl->add( vec3 );
100
101             // glTexCoord2f(s,t-dt);
102             sgSetVec2( vec2, s, t-dt );
103             tl->add( vec2 );
104             s += ds;
105
106             // glVertex3f( x*radius, y*radius, z*radius );
107             sgSetVec3( vec3, x*radius, y*radius, z*radius );
108             vl->add( vec3 );
109         }
110
111         ssgLeaf *slice = 
112             new ssgVtxTable ( GL_TRIANGLE_STRIP, vl, nl, tl, cl );
113
114         if ( vl->getNum() != nl->getNum() ) {
115             cout << "bad sphere1\n";
116             exit(-1);
117         }
118         if ( vl->getNum() != tl->getNum() ) {
119             cout << "bad sphere2\n";
120             exit(-1);
121         }
122         slice->setState( state );
123         slice->setCallback( SSG_CALLBACK_PREDRAW, predraw );
124         slice->setCallback( SSG_CALLBACK_POSTDRAW, postdraw );
125
126         sphere->addKid( slice );
127
128         t -= dt;
129     }
130
131     return sphere;
132 }