00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <simgear/compiler.h>
00025 #include <simgear/constants.h>
00026 #include <simgear/debug/logstream.hxx>
00027
00028 #include <iostream>
00029
00030 #include <osg/Node>
00031 #include <osg/Geometry>
00032 #include <osg/Geode>
00033 #include <osg/Array>
00034
00035
00036
00037 osg::Node*
00038 SGMakeSphere(double radius, int slices, int stacks)
00039 {
00040 float rho, drho, dtheta;
00041 float s, t, ds, dt;
00042 int i, j, imin, imax;
00043 float nsign = 1.0;
00044 osg::Geode* geode = new osg::Geode;
00045
00046 drho = SGD_PI / (float) stacks;
00047 dtheta = SGD_2PI / (float) slices;
00048
00049
00050
00051
00052
00053
00054 ds = 1.0 / slices;
00055 dt = 1.0 / stacks;
00056 t = 1.0;
00057 imin = 0;
00058 imax = stacks;
00059
00060
00061 for ( i = imin; i < imax; i++ ) {
00062 osg::Geometry* geometry = new osg::Geometry;
00063 osg::Vec3Array* vl = new osg::Vec3Array;
00064 osg::Vec3Array* nl = new osg::Vec3Array;
00065 osg::Vec2Array* tl = new osg::Vec2Array;
00066
00067 rho = i * drho;
00068 s = 0.0;
00069 for ( j = 0; j <= slices; j++ ) {
00070 double theta = (j == slices) ? 0.0 : j * dtheta;
00071 double x = -sin(theta) * sin(rho);
00072 double y = cos(theta) * sin(rho);
00073 double z = nsign * cos(rho);
00074
00075
00076 osg::Vec3 normal(x*nsign, y*nsign, z*nsign);
00077 normal.normalize();
00078 nl->push_back(normal);
00079
00080
00081 tl->push_back(osg::Vec2(s, t));
00082
00083
00084 vl->push_back(osg::Vec3(x*radius, y*radius, z*radius));
00085
00086 x = -sin(theta) * sin(rho+drho);
00087 y = cos(theta) * sin(rho+drho);
00088 z = nsign * cos(rho+drho);
00089
00090
00091 normal = osg::Vec3(x*nsign, y*nsign, z*nsign);
00092 normal.normalize();
00093 nl->push_back(normal);
00094
00095
00096 tl->push_back(osg::Vec2(s, t-dt));
00097 s += ds;
00098
00099
00100 vl->push_back(osg::Vec3(x*radius, y*radius, z*radius));
00101 }
00102
00103 if ( vl->size() != nl->size() ) {
00104 SG_LOG( SG_EVENT, SG_ALERT, "bad sphere1");
00105 exit(-1);
00106 }
00107 if ( vl->size() != tl->size() ) {
00108 SG_LOG( SG_EVENT, SG_ALERT, "bad sphere2");
00109 exit(-1);
00110 }
00111
00112
00113 osg::Vec4Array* cl = new osg::Vec4Array;
00114 cl->push_back(osg::Vec4(1, 1, 1, 1));
00115
00116 geometry->setUseDisplayList(false);
00117 geometry->setVertexArray(vl);
00118 geometry->setNormalArray(nl);
00119 geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
00120 geometry->setTexCoordArray(0, tl);
00121 geometry->setColorArray(cl);
00122 geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
00123 geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, vl->size()));
00124 geode->addDrawable(geometry);
00125
00126 t -= dt;
00127 }
00128
00129 return geode;
00130 }