1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
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.
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.
14#ifndef OSGSIM_SPHERESEGMENT
15#define OSGSIM_SPHERESEGMENT 1
17#include <osgSim/Export>
23#include <osg/BlendFunc>
24#include <osg/Geometry>
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:
34 - The specified area of the sphere surface.
36 - An edge line around the boundary of the specified area
37 of the sphere surface.
39 - Four <i>spokes</i>, where a spoke is the line from
40 the sphere's centre to a corner of the rendered area.
42 - Four planar areas, where the planar areas are formed
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
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.
60class OSGSIM_EXPORT SphereSegment: public osg::Geode
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.
68 sphereSegment->setDrawMask(SphereSegment::DrawMask(SphereSegment::SURFACE|SphereSegment::SPOKES));
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
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),
86 _drawMask(DrawMask(ALL))
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
104 SphereSegment(const osg::Vec3& centre, float radius, float azMin, float azMax, float elevMin, float elevMax, int density);
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
116 SphereSegment(const osg::Vec3& centre, float radius, const osg::Vec3& vec, float azRange, float elevRange, int density);
118 /** Copy constructor */
119 SphereSegment(const SphereSegment& rhs, const osg::CopyOp& co);
121 void traverse(osg::NodeVisitor& nv);
123 /** Set the centre point of the SphereSegment */
124 void setCentre(const osg::Vec3& c);
126 /** Get the centre point of the SphereSegment */
127 const osg::Vec3& getCentre() const;
129 /** Set the radius of the SphereSegment */
130 void setRadius(float r);
132 /** Get the radius of the SphereSegment */
133 float getRadius() const;
135 /** Set the area of the sphere segment
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)
142 void setArea(const osg::Vec3& vec, float azRange, float elevRange);
144 /** Get the area of the sphere segment
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)
151 void getArea(osg::Vec3& vec, float& azRange, float& elevRange) const;
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
159 void setArea(float azMin, float azMax, float elevMin, float elevMax);
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
167 void getArea(float &azMin, float &azMax, float &elevMin, float &elevMax) const;
169 /** Set the density of the sphere segment */
170 void setDensity(int d);
172 /** Get the density of the sphere segment */
173 int getDensity() const;
176 Specify the DrawMask.
177 @param dm Bitmask specifying which parts of the sphere segment should be drawn.
180 void setDrawMask(int dm);
182 /** Get the DrawMask */
183 int getDrawMask() const { return _drawMask; }
185 /** Set the color of the surface. */
186 void setSurfaceColor(const osg::Vec4& c);
188 /** Get the color of the surface. */
189 const osg::Vec4& getSurfaceColor() const { return (*_surfaceColor)[0]; }
191 /** Set the color of the spokes. */
192 void setSpokeColor(const osg::Vec4& c);
194 /** Get the color of the spokes. */
195 const osg::Vec4& getSpokeColor() const { return (*_spokeColor)[0]; }
197 /** Set the color of the edge line. */
198 void setEdgeLineColor(const osg::Vec4& c);
200 /** Get the color of the edge line. */
201 const osg::Vec4& getEdgeLineColor() const { return (*_edgeLineColor)[0]; }
203 /** Set the color of the planes. */
204 void setSideColor(const osg::Vec4& c);
206 /** Get the color of the planes. */
207 const osg::Vec4& getSideColor() const { return (*_sideColor)[0]; }
209 /** Set color of all components. */
210 void setAllColors(const osg::Vec4& c);
212 META_Node(osgSim, SphereSegment);
214 /** A list of vertex arrays representing a list of lines.*/
215 typedef std::vector< osg::ref_ptr<osg::Vec3Array> > LineList;
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);
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);
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);
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);
237 /** recompute the vertex positions of the rendering meshes/lines that represent the sphere segment.*/
238 void updatePositions();
240 /** recompute the primitives rendering meshes/lines thtat represent the sphere segment.*/
241 void updatePrimitives();
244 virtual void resizeGLObjectBuffers(unsigned int maxSize);
245 virtual void releaseGLObjects(osg::State* state = 0) const;
247 virtual osg::BoundingSphere computeBound() const;
251 void init(); // Shared constructor code, generates the drawables
253 void dirty(); // Force re-calling of gl functions and bounding boxes
255 // Sphere segment geometry details
258 float _azMin, _azMax, _elevMin, _elevMax;
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;
268 osg::ref_ptr<osg::Vec3Array> _vertices;
269 osg::ref_ptr<osg::Vec3Array> _normals;
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;
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;
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(); }