1 #include "utils/shapeutils.h"
7 #include <osg/PositionAttitudeTransform>
8 #include <osg/Geometry>
10 #include <osg/ShapeDrawable>
13 #include <osg/ShadeModel>
15 namespace ShapeUtils
{
16 osg::Geode
*createSphere(const osg::Vec4
&color
, float radius
)
18 osg::TessellationHints
*sphereHints
= new osg::TessellationHints
;
19 // sphereHints->setDetailRatio(0.1f);
20 // sphereHints->setCreateBody(true);
21 osg::Sphere
*sphere
= new osg::Sphere(osg::Vec3(0, 0, 0), radius
);
22 osg::ShapeDrawable
*sphereDrawable
= new osg::ShapeDrawable(sphere
, sphereHints
);
24 sphereDrawable
->setColor(color
);
26 osg::Geode
*geode
= new osg::Geode
;
27 geode
->addDrawable(sphereDrawable
);
32 osg::Geode
*createCube()
34 // Declare a group to act as root node of a scene:
35 // osg::Group* root = new osg::Group();
37 // Declare a box class (derived from shape class) instance
38 // This constructor takes an osg::Vec3 to define the center
39 // and a float to define the height, width and depth.
40 // (an overloaded constructor allows you to specify unique
41 // height, width and height values.)
42 osg::Box
*unitCube
= new osg::Box(osg::Vec3(0, 0, 0), 1.0f
);
44 // Declare an instance of the shape drawable class and initialize
45 // it with the unitCube shape we created above.
46 // This class is derived from 'drawable' so instances of this
47 // class can be added to Geode instances.
48 osg::ShapeDrawable
*unitCubeDrawable
= new osg::ShapeDrawable(unitCube
);
50 // Declare a instance of the geode class:
51 osg::Geode
*geode
= new osg::Geode();
53 // Add the unit cube drawable to the geode:
54 geode
->addDrawable(unitCubeDrawable
);
56 // osg::PolygonMode *pm = new osg::PolygonMode();
57 // pm->setMode( osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE );
59 // osg::StateSet *stateSet = new osg::StateSet();
60 // stateSet->setAttributeAndModes( pm,
61 // osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON );
62 // geode->setStateSet(stateSet);
64 // Add the geode to the scene:
68 osg::PositionAttitudeTransform
*createArrow(const osg::Vec4
&color
)
70 osg::ref_ptr
<osg::Geode
> geode
= new osg::Geode
;
74 osg::TessellationHints
*cylinderHints
= new osg::TessellationHints
;
76 cylinderHints
->setDetailRatio(0.1f
);
77 cylinderHints
->setCreateBody(true);
78 // cylinderHints->setCreateFrontFace(false);
79 // cylinderHints->setCreateBackFace(false);
80 osg::Cylinder
*cylinder
= new osg::Cylinder(osg::Vec3(0, 0, 0.4), radius
, 0.8);
81 // cylinder->setRotation(quat);
82 osg::ShapeDrawable
*cylinderDrawable
= new osg::ShapeDrawable(cylinder
, cylinderHints
);
83 cylinderDrawable
->setColor(color
);
84 geode
->addDrawable(cylinderDrawable
);
86 osg::TessellationHints
*coneHints
= new osg::TessellationHints
;
87 coneHints
->setDetailRatio(0.5f
);
88 coneHints
->setCreateBottom(true);
89 osg::Cone
*cone
= new osg::Cone(osg::Vec3(0, 0, 0.8), radius
* 2, 0.2);
90 // cone->setRotation(quat);
91 osg::ShapeDrawable
*coneDrawable
= new osg::ShapeDrawable(cone
, coneHints
);
92 coneDrawable
->setColor(color
);
93 geode
->addDrawable(coneDrawable
);
95 osg::PositionAttitudeTransform
*transform
= new osg::PositionAttitudeTransform();
96 transform
->addChild(geode
);
101 osg::Node
*create3DAxis()
103 osg::PositionAttitudeTransform
*xAxis
= createArrow(osg::Vec4(1, 0, 0, 1));
105 xAxis
->setAttitude(osg::Quat(M_PI
/ 2.0, osg::Vec3(0, 1, 0)));
107 osg::PositionAttitudeTransform
*yAxis
= createArrow(osg::Vec4(0, 1, 0, 1));
108 yAxis
->setAttitude(osg::Quat(-M_PI
/ 2.0, osg::Vec3(1, 0, 0)));
110 osg::PositionAttitudeTransform
*zAxis
= createArrow(osg::Vec4(0, 0, 1, 1));
112 osg::Node
*center
= createSphere(osg::Vec4(0.7, 0.7, .7, 1), 0.08);
114 osg::Group
*group
= new osg::Group();
115 group
->addChild(xAxis
);
116 group
->addChild(yAxis
);
117 group
->addChild(zAxis
);
118 group
->addChild(center
);
122 osg::Node
*createOrientatedTorus(float innerRadius
, float outerRadius
)
124 osg::Node
*node
= createTorus(innerRadius
, outerRadius
, 64, 32);
126 osg::PositionAttitudeTransform
*transform
= new osg::PositionAttitudeTransform();
128 transform
->addChild(node
);
130 osg::Quat q
= osg::Quat(
131 M_PI
/ 2, osg::Vec3d(1, 0, 0),
132 0, osg::Vec3d(0, 1, 0),
133 0, osg::Vec3d(0, 0, 1));
134 transform
->setAttitude(q
);
136 // transform->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
137 // node->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL, osg::StateAttribute::ON);
142 osg::Geode
*createTorus(float innerRadius
, float outerRadius
, float sweepCuts
, float sphereCuts
)
144 osg::ref_ptr
<osg::Geode
> geode
= new osg::Geode
;
146 bool create_body
= true;
149 float inner
= innerRadius
;
150 float outer
= outerRadius
;
151 float tube_radius
= (outer
- inner
) * 0.5;
152 float avg_center
= (inner
+ outer
) * 0.5;
154 float start_sweep
= 0; // this->getStartSweep();
155 float end_sweep
= osg::DegreesToRadians(360.0); // this->getEndSweep();
157 int torus_sweeps
= sweepCuts
;
158 int sphere_sweeps
= sphereCuts
;
160 float dsweep
= (end_sweep
- start_sweep
) / (float)torus_sweeps
;
161 float dphi
= osg::DegreesToRadians(360.0) / (float)sphere_sweeps
;
163 for (int j
= 0; j
< sphere_sweeps
; j
++) {
164 osg::Vec3Array
*vertices
= new osg::Vec3Array
;
165 osg::Vec3Array
*normals
= new osg::Vec3Array
;
167 float phi
= dphi
* (float)j
;
168 float cosPhi
= cosf(phi
);
169 float sinPhi
= sinf(phi
);
170 float next_cosPhi
= cosf(phi
+ dphi
);
171 float next_sinPhi
= sinf(phi
+ dphi
);
173 float z
= tube_radius
* sinPhi
;
174 float yPrime
= avg_center
+ tube_radius
* cosPhi
;
176 float next_z
= tube_radius
* next_sinPhi
;
177 float next_yPrime
= avg_center
+ tube_radius
* next_cosPhi
;
179 float old_x
= yPrime
* cosf(-dsweep
);
180 float old_y
= yPrime
* sinf(-dsweep
);
183 for (int i
= 0; i
< torus_sweeps
; ++i
) {
184 float sweep
= start_sweep
+ dsweep
* i
;
185 float cosSweep
= cosf(sweep
);
186 float sinSweep
= sinf(sweep
);
188 float x
= yPrime
* cosSweep
;
189 float y
= yPrime
* sinSweep
;
191 float next_x
= next_yPrime
* cosSweep
;
192 float next_y
= next_yPrime
* sinSweep
;
194 vertices
->push_back(osg::Vec3(next_x
, next_y
, next_z
));
195 vertices
->push_back(osg::Vec3(x
, y
, z
));
198 osg::Vec3
lateral(next_x
- x
, next_y
- y
, next_z
- z
);
199 osg::Vec3
longitudinal(x
- old_x
, y
- old_y
, z
- old_z
);
200 osg::Vec3 normal
= longitudinal
^ lateral
; // cross product
203 normals
->push_back(normal
);
204 normals
->push_back(normal
);
212 float last_sweep
= start_sweep
+ end_sweep
;
213 float cosLastSweep
= cosf(last_sweep
);
214 float sinLastSweep
= sinf(last_sweep
);
216 float x
= yPrime
* cosLastSweep
;
217 float y
= yPrime
* sinLastSweep
;
219 float next_x
= next_yPrime
* cosLastSweep
;
220 float next_y
= next_yPrime
* sinLastSweep
;
222 vertices
->push_back(osg::Vec3(next_x
, next_y
, next_z
));
223 vertices
->push_back(osg::Vec3(x
, y
, z
));
225 osg::Vec3
lateral(next_x
- x
, next_y
- y
, next_z
- z
);
226 osg::Vec3
longitudinal(x
- old_x
, y
- old_y
, z
- old_z
);
227 osg::Vec3 norm
= longitudinal
^ lateral
;
230 normals
->push_back(norm
);
231 normals
->push_back(norm
);
233 osg::ShadeModel
*shademodel
= new osg::ShadeModel
;
234 shademodel
->setMode(osg::ShadeModel::SMOOTH
);
236 osg::StateSet
*stateset
= new osg::StateSet
;
237 stateset
->setAttribute(shademodel
);
239 osg::ref_ptr
<osg::Geometry
> geometry
= new osg::Geometry
;
240 geometry
->setStateSet(stateset
);
242 geometry
->setVertexArray(vertices
);
244 osg::Vec4Array
*colors
= new osg::Vec4Array
;
245 colors
->push_back(osg::Vec4(1.0, 1.0, 0.0, 1.0)); // this->getColor());
246 geometry
->setColorArray(colors
);
247 geometry
->setColorBinding(osg::Geometry::BIND_OVERALL
);
249 geometry
->setNormalArray(normals
);
250 geometry
->setNormalBinding(osg::Geometry::BIND_PER_VERTEX
);
252 geometry
->addPrimitiveSet(
253 new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP
, 0,
255 geode
->addDrawable(geometry
.get());
257 } // endif create_body
259 return geode
.release();
262 osg::Geode
*createRhombicuboctahedron()
270 const double alpha
= 1; // 0.65;
271 const osg::Vec4 colors
[] = {
272 osg::Vec4(0.7, 0.5, 0.7, alpha
), // TFR
273 osg::Vec4(0.9, 0.9, 0.9, alpha
), // T
274 osg::Vec4(0.5, 0.7, 0.7, alpha
), // TFL
275 osg::Vec4(1.0, 0.7, 0.7, alpha
), // TS
276 osg::Vec4(0.7, 0.7, 1.0, alpha
), // TF
277 osg::Vec4(0.5, 0.0, 0.7, alpha
), // BFR
278 osg::Vec4(0.5, 0.5, 1.0, alpha
), // F
279 osg::Vec4(0.1, 0.5, 0.7, alpha
), // BFL
280 osg::Vec4(0.9, 0.5, 0.9, alpha
), // TR
281 osg::Vec4(0.5, 0.0, 0.5, alpha
), // R
282 osg::Vec4(1.0, 0.5, 0.7, alpha
), // TSR
283 osg::Vec4(0.2, 0.0, 0.2, alpha
), // BR
284 osg::Vec4(0.2, 0.2, 1.0, alpha
), // BF
285 osg::Vec4(0.7, 0.0, 0.2, alpha
), // BSR
286 osg::Vec4(0.1, 0.1, 0.1, alpha
), // B
287 osg::Vec4(0.5, 0.5, 0.2, alpha
), // BSL
288 osg::Vec4(0.9, 0.0, 0.4, alpha
), // SR
289 osg::Vec4(1.0, 0.2, 0.2, alpha
), // BS
290 osg::Vec4(1.0, 0.5, 0.5, alpha
), // S
291 osg::Vec4(0.7, 0.7, 0.5, alpha
), // SL
292 osg::Vec4(0.5, 0.9, 0.5, alpha
), // TL
293 osg::Vec4(0.5, 0.7, 0.5, alpha
), // L
294 osg::Vec4(1.0, 1.0, 0.7, alpha
), // TSL
295 osg::Vec4(0.2, 0.5, 0.2, alpha
), // BL
296 osg::Vec4(0.5, 0.0, 0.8, alpha
), // FR
297 osg::Vec4(0.5, 0.7, 1.0, alpha
) // FL
300 const double no
= -1.0;
301 const double po
= 1.0f
;
302 const double ps
= 1.0 + sqrt(1.0);
303 const double ns
= -ps
;
304 const osg::Vec3 vertices
[] = {
305 osg::Vec3(po
, po
, ps
),
306 osg::Vec3(po
, no
, ps
),
307 osg::Vec3(no
, po
, ps
),
308 osg::Vec3(no
, no
, ps
),
310 osg::Vec3(po
, ps
, po
),
311 osg::Vec3(po
, ps
, no
),
312 osg::Vec3(no
, ps
, po
),
313 osg::Vec3(no
, ps
, no
),
315 osg::Vec3(ps
, po
, po
),
316 osg::Vec3(ps
, po
, no
),
317 osg::Vec3(ps
, no
, po
),
318 osg::Vec3(ps
, no
, no
),
320 osg::Vec3(po
, po
, ns
),
321 osg::Vec3(po
, no
, ns
),
322 osg::Vec3(no
, po
, ns
),
323 osg::Vec3(no
, no
, ns
),
325 osg::Vec3(po
, ns
, po
),
326 osg::Vec3(po
, ns
, no
),
327 osg::Vec3(no
, ns
, po
),
328 osg::Vec3(no
, ns
, no
),
330 osg::Vec3(ns
, po
, po
),
331 osg::Vec3(ns
, po
, no
),
332 osg::Vec3(ns
, no
, po
),
333 osg::Vec3(ns
, no
, no
),
335 // bonus vertices to map unique colors
336 // we have only 24 regular vertices, but 26 faces
337 osg::Vec3(ps
, po
, no
), // copy from vertex 9
338 osg::Vec3(no
, ps
, no
) // copy from vertex 7
341 const unsigned int indices
[] = {
343 8, 4, 0, // TFR 45 -45
348 6, 20, 2, // TFL 45 45
350 1, 16, 3, // TS1 -45 0
356 12, 9, 5, // BFR 45 -135
361 14, 21, 7, // BFL 45 135
363 0, 1, 8, // TR1 0 -45
366 8, 10, 9, // R1 0 -90
369 1, 16, 10, // TSR -45 -45
371 13, 12, 11, // BR1 0 -135
374 5, 7, 12, // BF1 45 +-180
377 11, 17, 13, // BSR -45 -135
379 12, 13, 14, // B1 0 +-180
382 19, 23, 15, // BSL -45 135
384 11, 17, 16, // SR1 -45 -90
387 13, 15, 17, // BS1 -45 +-180
390 16, 17, 18, // S1 -90 X
393 18, 22, 19, // SL -45 90
396 2, 3, 20, // TL1 0 45
399 20, 22, 21, // L1 0 90
402 3, 18, 22, // TSL -45 45
404 14, 15, 23, // BL1 0 135
407 // last vertex is equal to vertex 9 to map a unique color
408 4, 5, 24, // FR 45 -90
411 // last vertex is equal to vertex 7 to map a unique color
412 6, 20, 25, // FL 45 90
416 osg::ShadeModel
*shademodel
= new osg::ShadeModel
;
418 shademodel
->setMode(osg::ShadeModel::FLAT
);
420 osg::StateSet
*stateset
= new osg::StateSet
;
421 stateset
->setAttribute(shademodel
);
423 osg::ref_ptr
<osg::Geometry
> geom
= new osg::Geometry
;
425 geom
->setStateSet(stateset
);
427 unsigned int vertexCount
= sizeof(vertices
) / sizeof(vertices
[0]);
428 osg::Vec3Array
*vertexArray
= new osg::Vec3Array(vertexCount
, const_cast<osg::Vec3
*>(&vertices
[0]));
429 geom
->setVertexArray(vertexArray
);
431 unsigned int indexCount
= sizeof(indices
) / sizeof(indices
[0]);
432 geom
->addPrimitiveSet(new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES
, indexCount
, indices
));
434 unsigned int colorCount
= sizeof(colors
) / sizeof(colors
[0]);
435 osg::Vec4Array
*colorArray
= new osg::Vec4Array(colorCount
, const_cast<osg::Vec4
*>(&colors
[0]));
436 geom
->setColorArray(colorArray
);
437 geom
->setColorBinding(osg::Geometry::BIND_PER_VERTEX
);
439 // geometry->setNormalArray(normals);
440 // geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
442 osg::ref_ptr
<osg::Geode
> geode
= new osg::Geode
;
443 geode
->addDrawable(geom
.get());
445 return geode
.release();