root/OpenSceneGraph/trunk/include/osgSim/SphereSegment @ 9409

Revision 9409, 12.2 kB (checked in by robert, 5 years ago)

Fixed warning & error

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#ifndef OSGSIM_SPHERESEGMENT
15#define OSGSIM_SPHERESEGMENT 1
16
17#include <osgSim/Export>
18
19#include <osg/Vec3>
20#include <osg/Vec4>
21#include <osg/Geode>
22#include <osg/Matrixd>
23#include <osg/BlendFunc>
24
25namespace osgSim{
26
27/**
28A SphereSegment is a Geode to represent an portion of a sphere (potentially
29the whole sphere). The sphere is aligned such that the line through the
30sphere's poles is parallel to the z axis. The sphere segment
31may be rendered various components switched on or off:
32
33    - The specified area of the sphere surface.
34
35    - An edge line around the boundary of the specified area
36      of the sphere surface.
37
38    - Four <i>spokes</i>, where a spoke is the line from
39      the sphere's centre to a corner of the rendered area.
40
41    - Four planar areas, where the planar areas are formed
42      between the spokes.
43
44Caveats:
45
46    - It's worth noting that the line through the sphere's poles is
47      parallel to the z axis. This has implications when specifying the
48      area to be rendered, and specifying areas where the centre of
49      the rendered area <i>is</i> the Z axis may lead to unexpected
50      geometry.
51
52    - It's possible to render the whole sphere by specifying elevation
53      and azimuth ranges round the full 360 degrees. When doing
54      so you may consider switching the planes, spokes, and edge lines
55      off, to avoid rendering artefacts, e.g. the upper and lower
56      planes will be coincident.
57
58*/
59class OSGSIM_EXPORT SphereSegment: public osg::Geode
60{
61public:
62
63    /**
64    DrawMask represents a bit field, the values of which may be OR'ed together
65    to specify which parts of the sphere segment should be drawn. E.g.
66    \code
67    sphereSegment->setDrawMask(SphereSegment::DrawMask(SphereSegment::SURFACE|SphereSegment::SPOKES));
68    \endcode
69    */
70    enum DrawMask{
71        SURFACE =   0x00000001, ///< Draw the specified area on the sphere's surface
72        SPOKES =    0x00000002, ///< Draw the spokes from the sphere's centre to the surface's corners
73        EDGELINE =  0x00000008, ///< Draw the line round the edge of the area on the sphere's surface
74        SIDES =     0x00000010, ///< Draw the planes from the sphere's centre to the edge of the sphere's surface
75        ALL =       0x7fffffff  ///< Draw every part of the sphere segment
76    };
77
78
79    /** Default constructor. */
80    SphereSegment():osg::Geode(),
81                    _centre(0.0f,0.0f,0.0f), _radius(1.0f),
82                    _azMin(0.0f), _azMax(osg::PI/2.0f),
83                    _elevMin(0.0f), _elevMax(osg::PI/2.0f),
84                    _density(10),
85                    _drawMask(DrawMask(ALL))
86    {
87        init();
88    }
89
90    /**
91    Construct by angle ranges. Note that the azimuth 'zero' is the Y axis; specifying
92    an azimuth range from azMin -osg::PI/2.0f to azMax osg::PI/2.0f will cover the
93    'top half' of the circle in the XY plane. The elev angles are 'out' of the 'zero'
94    XY plane with +ve angles above the plane, and -ve angles below.
95    @param centre       sphere centre
96    @param radius       radius of sphere
97    @param azMin        azimuth minimum
98    @param azMax        azimuth maximum
99    @param elevMin      elevation minimum
100    @param elevMax      elevation maximum
101    @param density      number of units to divide the azimuth and elevation ranges into
102    */
103    SphereSegment(const osg::Vec3& centre, float radius, float azMin, float azMax,
104                    float elevMin, float elevMax, int density):
105        osg::Geode(),
106        _centre(centre), _radius(radius),
107        _azMin(azMin), _azMax(azMax),
108        _elevMin(elevMin), _elevMax(elevMax),
109        _density(density),
110        _drawMask(DrawMask(ALL))
111    {
112        init();
113    }
114
115    /**
116    Construct by vector.
117    @param centre       sphere centre
118    @param radius       radius of sphere
119    @param vec          vector pointing from sphere centre to centre point
120                        of rendered area on sphere surface
121    @param azRange      azimuth range in radians (with centre along vec)
122    @param elevRange    elevation range in radians (with centre along vec)
123    @param density      number of units to divide the azimuth and elevation ranges into
124    */
125    SphereSegment(const osg::Vec3& centre, float radius, const osg::Vec3& vec, float azRange,
126                    float elevRange, int density);
127
128    /** Copy constructor */
129    SphereSegment(const SphereSegment& rhs, const osg::CopyOp& co):
130        osg::Geode(rhs,co),
131        _centre(rhs._centre), _radius(rhs._radius),
132        _azMin(rhs._azMin), _azMax(rhs._azMax),
133        _elevMin(rhs._elevMin), _elevMax(rhs._elevMax),
134        _density(rhs._density),
135        _drawMask(rhs._drawMask)
136    {
137        init();
138    }
139
140    /** Set the centre point of the SphereSegment */
141    void setCentre(const osg::Vec3& c);
142
143    /** Get the centre point of the SphereSegment */
144    const osg::Vec3& getCentre() const;
145
146    /** Set the radius of the SphereSegment */
147    void setRadius(float r);
148
149    /** Get the radius of the SphereSegment */
150    float getRadius() const;
151
152    /** Set the area of the sphere segment
153
154    @param vec          vector pointing from sphere centre to centre point
155                        of rendered area on sphere surface
156    @param azRange      azimuth range in radians (with centre along vec)
157    @param elevRange    elevation range in radians (with centre along vec)
158    */
159    void setArea(const osg::Vec3& vec, float azRange, float elevRange);
160
161    /** Get the area of the sphere segment
162
163    @param vec          vector pointing from sphere centre to centre point
164                        of rendered area on sphere surface (normalized)
165    @param azRange      azimuth range in radians (with centre along vec)
166    @param elevRange    elevation range in radians (with centre along vec)
167    */
168    void getArea(osg::Vec3& vec, float& azRange, float& elevRange) const;
169
170    /** Set the area of the sphere segment
171    @param azMin        azimuth minimum
172    @param azMax        azimuth maximum
173    @param elevMin      elevation minimum
174    @param elevMax      elevation maximum
175    */
176    void setArea(float azMin, float azMax, float elevMin, float elevMax);
177
178    /** Get the area of the sphere segment
179    @param azMin        azimuth minimum
180    @param azMax        azimuth maximum
181    @param elevMin      elevation minimum
182    @param elevMax      elevation maximum
183    */
184    void getArea(float &azMin, float &azMax, float &elevMin, float &elevMax) const;
185
186    /** Set the density of the sphere segment */
187    void setDensity(int d);
188
189    /** Get the density of the sphere segment */
190    int getDensity() const;
191
192    /**
193    Specify the DrawMask.
194    @param dm   Bitmask specifying which parts of the sphere segment should be drawn.
195    @see DrawMask
196    */
197    void setDrawMask(DrawMask dm);
198
199    /** Get the DrawMask */
200    DrawMask getDrawMask() const { return _drawMask; }
201
202    /** Set the color of the surface. */
203    void setSurfaceColor(const osg::Vec4& c);
204
205    /** Get the color of the surface. */
206    osg::Vec4 getSurfaceColor() const { return _surfaceColor; }
207
208    /** Set the color of the spokes. */
209    void setSpokeColor(const osg::Vec4& c);
210
211    /** Get the color of the spokes. */
212    osg::Vec4 getSpokeColor() const { return _spokeColor; }
213
214    /** Set the color of the edge line. */
215    void setEdgeLineColor(const osg::Vec4& c);
216
217    /** Get the color of the edge line. */
218    osg::Vec4 getEdgeLineColor() const { return _edgeLineColor; }
219
220    /** Set the color of the planes. */
221    void setSideColor(const osg::Vec4& c);
222
223    /** Get the color of the planes. */
224    osg::Vec4 getSideColor() const { return _planeColor; }
225
226    /** Set color of all components. */
227    void setAllColors(const osg::Vec4& c);
228
229    META_Node(osgSim, SphereSegment);
230   
231    /** A list of vertex arrays representing a list of lines.*/
232    typedef std::vector< osg::ref_ptr<osg::Vec3Array> > LineList;
233   
234    /** Compute the interesection lines between subgraph and this sphere segment.
235      * The matrix is the transform that takes the subgraph into the same coordiante frame as the sphere segment.
236      * The resulting intersections are in the coordinate frame of the sphere segment. */
237    LineList computeIntersection(const osg::Matrixd& matrix, osg::Node* subgraph);
238
239    /** Compute the interesection lines between specified drawable and this sphere segment.
240      * The matrix is the transform that takes the subgraph into the same coordiante frame as the sphere segment.
241      * The resulting intersections are in the coordinate frame of the sphere segment. */
242    LineList computeIntersection(const osg::Matrixd& matrix, osg::Drawable* drawable);
243
244    /** Compute the interesection lines between subgraph and this sphere segment.
245      * The matrix is the transform that takes the subgraph into the same coordiante frame as the sphere segment.
246      * The resulting intersections are in the coordinate frame of the sphere segment. */
247    osg::Node* computeIntersectionSubgraph(const osg::Matrixd& matrix, osg::Node* subgraph);
248
249    /** Compute the interesection lines between specified drawable and this sphere segment.
250      * The matrix is the transform that takes the subgraph into the same coordiante frame as the sphere segment.
251      * The resulting intersections are in the coordinate frame of the sphere segment. */
252    osg::Node* computeIntersectionSubgraph(const osg::Matrixd& matrix, osg::Drawable* drawable);
253
254
255private:
256
257    void init();    // Shared constructor code, generates the drawables
258
259    void dirtyAllDrawableDisplayLists();    // Force re-calling of gl functions
260    void dirtyAllDrawableBounds();          // Force recalculation of bound geometry
261
262    // SphereSegment is actually made up of a number of Drawable classes,
263    // all of which are nested private classes, as declared below. These
264    // classes are defined in the .cpp for minimum visibility and physical
265    // coupling. (Reduces time spent compiling! :-)
266    //
267    // Each of the nested classes holds a pointer to the SphereSegment
268    // 'parent', which stores the geometry details, and performs any
269    // work required. The nested classes are lightweight objects which
270    // just pass the work on.
271    //
272    // Why are things done with these sub-Drawables? Alpha-blended
273    // Drawables need to be drawn last, depth sorted, and the various
274    // components of a SphereSegment also need to be depth sorted
275    // against one another (they may all be drawn with alpha blending).
276    // Making these Drawables allows us to get the OSG to depth sort
277    // for us.
278
279    class Surface;
280    friend class Surface;
281    bool Surface_computeBound(osg::BoundingBox&) const;
282    void Surface_drawImplementation(osg::State&) const;
283
284    class EdgeLine;
285    friend class EdgeLine;
286    bool EdgeLine_computeBound(osg::BoundingBox&) const;
287    void EdgeLine_drawImplementation(osg::State&) const;
288
289    enum BoundaryAngle{MIN,MAX};        // Why here and not in Side class? Because we can't forward
290    enum SideOrientation{AZIM,ELEV};   // declare enums, Side is in the .cpp, and this is tidier...
291    class Side;
292    friend class Side;
293    bool Side_computeBound(osg::BoundingBox&, SideOrientation, BoundaryAngle) const;
294    void Side_drawImplementation(osg::State&, SideOrientation, BoundaryAngle) const;
295
296    class Spoke;
297    friend class Spoke;
298    bool Spoke_computeBound(osg::BoundingBox&, BoundaryAngle, BoundaryAngle) const;
299    void Spoke_drawImplementation(osg::State&, BoundaryAngle, BoundaryAngle) const;
300
301    // Sphere segment geometry details
302    osg::Vec3 _centre;
303    float _radius;
304    float _azMin, _azMax, _elevMin, _elevMax;
305    int _density;
306
307    // Draw details
308    DrawMask _drawMask;
309    osg::Vec4 _surfaceColor;
310    osg::Vec4 _spokeColor;
311    osg::Vec4 _edgeLineColor;
312    osg::Vec4 _planeColor;
313};
314
315}
316
317#endif
Note: See TracBrowser for help on using the browser.