openscenegraph
SphereSegment
Go to the documentation of this file.
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#include <osg/Geometry>
25
26namespace osgSim{
27
28/**
29A SphereSegment is a Geode to represent an portion of a sphere (potentially
30the whole sphere). The sphere is aligned such that the line through the
31sphere's poles is parallel to the z axis. The sphere segment
32may be rendered various components switched on or off:
33
34 - The specified area of the sphere surface.
35
36 - An edge line around the boundary of the specified area
37 of the sphere surface.
38
39 - Four <i>spokes</i>, where a spoke is the line from
40 the sphere's centre to a corner of the rendered area.
41
42 - Four planar areas, where the planar areas are formed
43 between the spokes.
44
45Caveats:
46
47 - It's worth noting that the line through the sphere's poles is
48 parallel to the z axis. This has implications when specifying the
49 area to be rendered, and specifying areas where the centre of
50 the rendered area <i>is</i> the Z axis may lead to unexpected
51 geometry.
52
53 - It's possible to render the whole sphere by specifying elevation
54 and azimuth ranges round the full 360 degrees. When doing
55 so you may consider switching the planes, spokes, and edge lines
56 off, to avoid rendering artifacts, e.g. the upper and lower
57 planes will be coincident.
58
59*/
60class OSGSIM_EXPORT SphereSegment: public osg::Geode
61{
62public:
63
64 /**
65 DrawMask represents a bit field, the values of which may be OR'ed together
66 to specify which parts of the sphere segment should be drawn. E.g.
67 \code
68 sphereSegment->setDrawMask(SphereSegment::DrawMask(SphereSegment::SURFACE|SphereSegment::SPOKES));
69 \endcode
70 */
71 enum DrawMask{
72 SURFACE = 0x00000001, ///< Draw the specified area on the sphere's surface
73 SPOKES = 0x00000002, ///< Draw the spokes from the sphere's centre to the surface's corners
74 EDGELINE = 0x00000008, ///< Draw the line round the edge of the area on the sphere's surface
75 SIDES = 0x00000010, ///< Draw the planes from the sphere's centre to the edge of the sphere's surface
76 ALL = 0x7fffffff ///< Draw every part of the sphere segment
77 };
78
79
80 /** Default constructor. */
81 SphereSegment():osg::Geode(),
82 _centre(0.0f,0.0f,0.0f), _radius(1.0f),
83 _azMin(0.0f), _azMax(osg::PI/2.0f),
84 _elevMin(0.0f), _elevMax(osg::PI/2.0f),
85 _density(10),
86 _drawMask(DrawMask(ALL))
87 {
88 init();
89 }
90
91 /**
92 Construct by angle ranges. Note that the azimuth 'zero' is the Y axis; specifying
93 an azimuth range from azMin -PI/2.0f to azMax PI/2.0f will cover the
94 'top half' of the circle in the XY plane. The elev angles are 'out' of the 'zero'
95 XY plane with +ve angles above the plane, and -ve angles below.
96 @param centre sphere centre
97 @param radius radius of sphere
98 @param azMin azimuth minimum
99 @param azMax azimuth maximum
100 @param elevMin elevation minimum
101 @param elevMax elevation maximum
102 @param density number of units to divide the azimuth and elevation ranges into
103 */
104 SphereSegment(const osg::Vec3& centre, float radius, float azMin, float azMax, float elevMin, float elevMax, int density);
105
106 /**
107 Construct by vector.
108 @param centre sphere centre
109 @param radius radius of sphere
110 @param vec vector pointing from sphere centre to centre point
111 of rendered area on sphere surface
112 @param azRange azimuth range in radians (with centre along vec)
113 @param elevRange elevation range in radians (with centre along vec)
114 @param density number of units to divide the azimuth and elevation ranges into
115 */
116 SphereSegment(const osg::Vec3& centre, float radius, const osg::Vec3& vec, float azRange, float elevRange, int density);
117
118 /** Copy constructor */
119 SphereSegment(const SphereSegment& rhs, const osg::CopyOp& co);
120
121 void traverse(osg::NodeVisitor& nv);
122
123 /** Set the centre point of the SphereSegment */
124 void setCentre(const osg::Vec3& c);
125
126 /** Get the centre point of the SphereSegment */
127 const osg::Vec3& getCentre() const;
128
129 /** Set the radius of the SphereSegment */
130 void setRadius(float r);
131
132 /** Get the radius of the SphereSegment */
133 float getRadius() const;
134
135 /** Set the area of the sphere segment
136
137 @param vec vector pointing from sphere centre to centre point
138 of rendered area on sphere surface
139 @param azRange azimuth range in radians (with centre along vec)
140 @param elevRange elevation range in radians (with centre along vec)
141 */
142 void setArea(const osg::Vec3& vec, float azRange, float elevRange);
143
144 /** Get the area of the sphere segment
145
146 @param vec vector pointing from sphere centre to centre point
147 of rendered area on sphere surface (normalized)
148 @param azRange azimuth range in radians (with centre along vec)
149 @param elevRange elevation range in radians (with centre along vec)
150 */
151 void getArea(osg::Vec3& vec, float& azRange, float& elevRange) const;
152
153 /** Set the area of the sphere segment
154 @param azMin azimuth minimum
155 @param azMax azimuth maximum
156 @param elevMin elevation minimum
157 @param elevMax elevation maximum
158 */
159 void setArea(float azMin, float azMax, float elevMin, float elevMax);
160
161 /** Get the area of the sphere segment
162 @param azMin azimuth minimum
163 @param azMax azimuth maximum
164 @param elevMin elevation minimum
165 @param elevMax elevation maximum
166 */
167 void getArea(float &azMin, float &azMax, float &elevMin, float &elevMax) const;
168
169 /** Set the density of the sphere segment */
170 void setDensity(int d);
171
172 /** Get the density of the sphere segment */
173 int getDensity() const;
174
175 /**
176 Specify the DrawMask.
177 @param dm Bitmask specifying which parts of the sphere segment should be drawn.
178 @see DrawMask
179 */
180 void setDrawMask(int dm);
181
182 /** Get the DrawMask */
183 int getDrawMask() const { return _drawMask; }
184
185 /** Set the color of the surface. */
186 void setSurfaceColor(const osg::Vec4& c);
187
188 /** Get the color of the surface. */
189 const osg::Vec4& getSurfaceColor() const { return (*_surfaceColor)[0]; }
190
191 /** Set the color of the spokes. */
192 void setSpokeColor(const osg::Vec4& c);
193
194 /** Get the color of the spokes. */
195 const osg::Vec4& getSpokeColor() const { return (*_spokeColor)[0]; }
196
197 /** Set the color of the edge line. */
198 void setEdgeLineColor(const osg::Vec4& c);
199
200 /** Get the color of the edge line. */
201 const osg::Vec4& getEdgeLineColor() const { return (*_edgeLineColor)[0]; }
202
203 /** Set the color of the planes. */
204 void setSideColor(const osg::Vec4& c);
205
206 /** Get the color of the planes. */
207 const osg::Vec4& getSideColor() const { return (*_sideColor)[0]; }
208
209 /** Set color of all components. */
210 void setAllColors(const osg::Vec4& c);
211
212 META_Node(osgSim, SphereSegment);
213
214 /** A list of vertex arrays representing a list of lines.*/
215 typedef std::vector< osg::ref_ptr<osg::Vec3Array> > LineList;
216
217 /** Compute the intersection lines between subgraph and this sphere segment.
218 * The matrix is the transform that takes the subgraph into the same coordinate frame as the sphere segment.
219 * The resulting intersections are in the coordinate frame of the sphere segment. */
220 LineList computeIntersection(const osg::Matrixd& matrix, osg::Node* subgraph);
221
222 /** Compute the intersection lines between specified drawable and this sphere segment.
223 * The matrix is the transform that takes the subgraph into the same coordinate frame as the sphere segment.
224 * The resulting intersections are in the coordinate frame of the sphere segment. */
225 LineList computeIntersection(const osg::Matrixd& matrix, osg::Drawable* drawable);
226
227 /** Compute the intersection lines between subgraph and this sphere segment.
228 * The matrix is the transform that takes the subgraph into the same coordinate frame as the sphere segment.
229 * The resulting intersections are in the coordinate frame of the sphere segment. */
230 osg::Node* computeIntersectionSubgraph(const osg::Matrixd& matrix, osg::Node* subgraph);
231
232 /** Compute the intersection lines between specified drawable and this sphere segment.
233 * The matrix is the transform that takes the subgraph into the same coordinate frame as the sphere segment.
234 * The resulting intersections are in the coordinate frame of the sphere segment. */
235 osg::Node* computeIntersectionSubgraph(const osg::Matrixd& matrix, osg::Drawable* drawable);
236
237 /** recompute the vertex positions of the rendering meshes/lines that represent the sphere segment.*/
238 void updatePositions();
239
240 /** recompute the primitives rendering meshes/lines thtat represent the sphere segment.*/
241 void updatePrimitives();
242
243
244 virtual void resizeGLObjectBuffers(unsigned int maxSize);
245 virtual void releaseGLObjects(osg::State* state = 0) const;
246
247 virtual osg::BoundingSphere computeBound() const;
248
249private:
250
251 void init(); // Shared constructor code, generates the drawables
252
253 void dirty(); // Force re-calling of gl functions and bounding boxes
254
255 // Sphere segment geometry details
256 osg::Vec3 _centre;
257 float _radius;
258 float _azMin, _azMax, _elevMin, _elevMax;
259 int _density;
260
261 // Draw details
262 int _drawMask;
263 osg::ref_ptr<osg::Vec4Array> _surfaceColor;
264 osg::ref_ptr<osg::Vec4Array> _spokeColor;
265 osg::ref_ptr<osg::Vec4Array> _edgeLineColor;
266 osg::ref_ptr<osg::Vec4Array> _sideColor;
267
268 osg::ref_ptr<osg::Vec3Array> _vertices;
269 osg::ref_ptr<osg::Vec3Array> _normals;
270
271 osg::ref_ptr<osg::Geometry> _surfaceGeometry;
272 osg::ref_ptr<osg::Geometry> _spokesGeometry;
273 osg::ref_ptr<osg::Geometry> _edgeLineGeometry;
274 osg::ref_ptr<osg::Geometry> _sidesGeometry;
275
276 osg::ref_ptr<osg::StateSet> _litOpaqueState;
277 osg::ref_ptr<osg::StateSet> _unlitOpaqueState;
278 osg::ref_ptr<osg::StateSet> _litTransparentState;
279 osg::ref_ptr<osg::StateSet> _unlitTransparentState;
280
281 osg::StateSet* getLitStateSet(const osg::Vec4& color) { return (color.a()<1.0) ? _litTransparentState.get() : _litOpaqueState.get(); }
282 osg::StateSet* getUnlitStateSet(const osg::Vec4& color) { return (color.a()<1.0) ? _unlitTransparentState.get() : _unlitOpaqueState.get(); }
283
284};
285
286}
287
288#endif