changed: gcc8 base update
[opensg.git] / Examples / Simple / clipplanecaps2.cpp
blob08fc710958cba5aafbdb6df0bc86fa968bffa9d3
1 // OpenSG example: ClipPlaneCaps2
2 //
3 // Demonstrates the use of the ClipPlaneChunk, StencilChunk for capping of
4 // clipped geometry.
5 //
6 // This example uses VisitSubTree cores in order to minimize the memory
7 // footprint and in order cleanly separate the scene from the clipping
8 // graph structure.
9 //
10 // This examples allows creation of a box and a torus. Additionally, two clip
11 // planes can be set up. On clipping the geometry caps are used to repair the
12 // clipped geometry.
14 // User interface:
15 // a) mouse => standard navigator
16 // b) keyboard =>
17 // '1': enable/disable clip plane 0
18 // '2': enable/disable clip plane 1
19 // '3': enable/disable box geometry
20 // '4': enable/disable torus geometry
21 // 'n': move clip plane 0 opposite to the normal direction of the plane
22 // 'm': move clip plane 0 in the normal direction of the plane
23 // ',': move clip plane 1 opposite to the normal direction of the plane
24 // '.': move clip plane 1 in the normal direction of the plane
25 // 'q': move box in -x direction
26 // 'w': move box in +x direction
27 // 'a': move box in -y direction
28 // 's': move box in +y direction
29 // 'y': move box in -z direction
30 // 'x': move box in +z direction
31 // 'e': move torus in -x direction
32 // 'r': move torus in +x direction
33 // 'd': move torus in -y direction
34 // 'f': move torus in +y direction
35 // 'c': move torus in -z direction
36 // 'v': move torus in +z direction
37 // 'p': create a png from scene with the graphviz tool output
39 // This example was contributed by Johannes Brunen
41 #include <vector>
42 #include <boost/shared_ptr.hpp>
43 #include <boost/foreach.hpp>
44 #include <boost/filesystem.hpp>
46 #ifdef OSG_BUILD_ACTIVE
48 #include <OSGGLUT.h>
49 #include <OSGConfig.h>
50 #include <OSGSimpleGeometry.h>
51 #include <OSGPassiveWindow.h>
52 #include <OSGSimpleSceneManager.h>
53 #include <OSGSceneFileHandler.h>
54 #include <OSGNameAttachment.h>
56 #include <OSGMultiSwitch.h>
57 #include <OSGVisitSubTree.h>
58 #include <OSGGroupingStage.h>
59 #include <OSGMaterialGroup.h>
60 #include <OSGMaterialChunkOverrideGroup.h>
61 #include <OSGChunkMaterial.h>
62 #include <OSGMultiPassMaterial.h>
63 #include <OSGClipPlaneChunk.h>
64 #include <OSGStencilChunk.h>
65 #include <OSGPolygonChunk.h>
66 #include <OSGMaterialChunk.h>
67 #include <OSGColorMaskChunk.h>
68 #include <OSGDepthChunk.h>
69 #include <OSGFieldContainerUtils.h>
70 #include <OSGSceneGraphUtils.h>
71 #include <OSGContainerCollection.h>
72 #include <OSGDotFileGeneratorGraphOp.h>
74 #else // OSG_BUILD_ACTIVE
76 #include <OpenSG/OSGGLUT.h>
77 #include <OpenSG/OSGConfig.h>
78 #include <OpenSG/OSGSimpleGeometry.h>
79 #include <OpenSG/OSGPassiveWindow.h>
80 #include <OpenSG/OSGSimpleSceneManager.h>
81 #include <OpenSG/OSGSceneFileHandler.h>
82 #include <OpenSG/OSGNameAttachment.h>
84 #include <OpenSG/OSGMultiSwitch.h>
85 #include <OpenSG/OSGVisitSubTree.h>
86 #include <OpenSG/OSGGroupingStage.h>
87 #include <OpenSG/OSGMaterialGroup.h>
88 #include <OpenSG/OSGMaterialChunkOverrideGroup.h>
89 #include <OpenSG/OSGChunkMaterial.h>
90 #include <OpenSG/OSGMultiPassMaterial.h>
91 #include <OpenSG/OSGClipPlaneChunk.h>
92 #include <OpenSG/OSGStencilChunk.h>
93 #include <OpenSG/OSGPolygonChunk.h>
94 #include <OpenSG/OSGMaterialChunk.h>
95 #include <OpenSG/OSGColorMaskChunk.h>
96 #include <OpenSG/OSGDepthChunk.h>
97 #include <OpenSG/OSGFieldContainerUtils.h>
98 #include <OpenSG/OSGSceneGraphUtils.h>
99 #include <OpenSG/OSGContainerCollection.h>
100 #include <OpenSG/OSGDotFileGeneratorGraphOp.h>
103 #endif // OSG_BUILD_ACTIVE
106 // Graphviz related globals
108 const char* graphviz_dot_executale = "c:/utils/python32/tools/Graphviz/bin/dot.exe";
109 const char* graphviz_output_file = "d:/out.dot";
112 // the number of clipping planes supported by the demo. Define a plane color
113 // for each.
115 const int iNumClipPlanes = 2;
116 OSG::Color4f planeCol[iNumClipPlanes] = { OSG::Color4f(0.f,1.f,0.f,1.f), OSG::Color4f(0.f,0.f,1.f,1.f) };
119 // convenience type
121 typedef std::vector<OSG::NodeRefPtr> VecNodesT;
124 // transport container for the actual clip plane data
126 struct ClipPlaneData
128 OSG::Vec4f _equation;
129 bool _enabled;
131 ClipPlaneData(void) : _equation(), _enabled(false) {}
134 typedef std::vector<ClipPlaneData> VecCPData;
137 // The clipplane scene manager extension smart pointer
139 class ClippingSceneManager;
140 typedef boost::shared_ptr<ClippingSceneManager> ClippingSceneManagerPtr;
143 // global state
145 VecCPData vecClipPlaneData; // transport clip plane info
146 VecNodesT vecGeometries; // box and torus
147 ClippingSceneManagerPtr mgr;
150 // for each clip plane these data are necessary
152 struct ClipPlaneDetails
154 OSG::ClipPlaneChunkRefPtr _clipPlaneChunk;
155 OSG::NodeRefPtr _clipPlaneBeacon;
156 OSG::GeometryRefPtr _planeGeometryCore;
157 OSG::TransformRefPtr _planeTrafoCore;
158 OSG::MaterialChunkRefPtr _planeMaterialChunk;
159 OSG::PolygonChunkRefPtr _planePolygonChunk;
161 ClipPlaneDetails(void):
162 _clipPlaneChunk (NULL),
163 _clipPlaneBeacon (NULL),
164 _planeGeometryCore (NULL),
165 _planeTrafoCore (NULL),
166 _planeMaterialChunk(NULL),
167 _planePolygonChunk (NULL)
172 typedef std::vector<ClipPlaneDetails> VecCPDetailsT;
175 // Some global convenience functions
178 //----- createChunkMaterial ---------------------------------------------------
180 OSG::ChunkMaterialTransitPtr createChunkMaterial(const OSG::Color3f& col)
182 using namespace OSG;
184 ChunkMaterialUnrecPtr mat = ChunkMaterial::create();
186 MaterialChunkUnrecPtr materialChunk = MaterialChunk::create();
187 PolygonChunkUnrecPtr polygonChunk = PolygonChunk::create();
189 materialChunk->setAmbient (Color4f(0.5*col[0], 0.5*col[1], 0.5*col[2], 1.0f));
190 materialChunk->setDiffuse (Color4f( col[0], col[1], col[2], 1.0f));
191 materialChunk->setEmission (Color4f( 0.0f, 0.0f, 0.0f, 1.0f));
192 materialChunk->setSpecular (Color4f( 0.8f, 0.8f, 0.8f, 1.0f));
193 materialChunk->setShininess (20.f);
195 polygonChunk->setFrontMode(GL_FILL);
196 polygonChunk->setBackMode(GL_FILL);
197 polygonChunk->setOffsetFactor(1.f);
198 polygonChunk->setOffsetBias(1.f);
199 polygonChunk->setOffsetFill(true);
200 polygonChunk->setCullFace(GL_NONE);
202 mat->addChunk(materialChunk);
203 mat->addChunk(polygonChunk);
205 return ChunkMaterialTransitPtr(mat);
208 //----- BuildGeometry ---------------------------------------------------------
210 enum {
211 TORUS_GEOMETRY = 1,
212 BOX_GEOMETRY = 2
215 OSG::NodeTransitPtr BuildGeometry(int kind, const OSG::Matrix& matrix, const OSG::Color3f& color)
217 using namespace OSG;
219 GeometryUnrecPtr geometryCore = NULL;
221 switch (kind)
223 case TORUS_GEOMETRY: geometryCore = makeTorusGeo(2, 6, 8, 16); break;
224 case BOX_GEOMETRY: geometryCore = makeBoxGeo(15, 15, 15, 1, 1, 1); break;
225 default:
226 assert(false);
229 ChunkMaterialUnrecPtr material = createChunkMaterial(color);
230 geometryCore->setMaterial(material);
232 TransformUnrecPtr transformCore = Transform::create();
233 transformCore->setMatrix(matrix);
235 NodeUnrecPtr transformNode = makeNodeFor(transformCore);
236 NodeUnrecPtr geometryNode = makeNodeFor(geometryCore);
238 setName(transformNode, "transformNode");
239 setName(geometryNode, "geometryNode");
241 transformNode->addChild(geometryNode);
243 return NodeTransitPtr(transformNode);
246 //----- BuildProxyGeometry ----------------------------------------------------
248 OSG::NodeTransitPtr BuildProxyGeometry(int kind, const OSG::Matrix& matrix, const OSG::Color3f& color)
250 using namespace OSG;
252 NodeUnrecPtr prototype = BuildGeometry(kind, Matrix(), color);
254 VisitSubTreeUnrecPtr visitTreeCore = VisitSubTree::create();
255 visitTreeCore->setSubTreeRoot(prototype);
257 ContainerCollectionUnrecPtr cc = ContainerCollection::create();
258 cc->addContainer(prototype);
260 TransformUnrecPtr transformCore = Transform::create();
261 transformCore->setMatrix(matrix);
263 NodeUnrecPtr visitTreeNode = makeNodeFor(visitTreeCore);
264 visitTreeNode->addAttachment(cc);
266 NodeUnrecPtr prototype_proxy = Node::create();
267 prototype_proxy->setCore(transformCore);
268 prototype_proxy->addChild(visitTreeNode);
270 setName(prototype, "prototype");
271 setName(prototype_proxy, "prototype_proxy");
272 setName(visitTreeNode, "visitTreeNode");
274 return NodeTransitPtr(prototype_proxy);
278 // The clipplane scene manager extension
280 class ClippingSceneManager
282 public:
283 OSG::Node* getInternalRoot () { return _root; }
284 OSG::Node* getRoot () { return _clippingRoot; }
285 void setRoot (OSG::Node* root);
287 void showAll () { _mgr->showAll(); }
288 void redraw () { _mgr->redraw(); }
289 void resize (OSG::UInt16 width, OSG::UInt16 height) { _mgr->resize(width,height); }
290 void mouseMove (OSG::Int16 x, OSG::Int16 y) { _mgr->mouseMove(x,y); }
291 void mouseButtonPress (OSG::UInt16 button, OSG::Int16 x, OSG::Int16 y) { _mgr->mouseButtonPress(button,x,y); }
292 void mouseButtonRelease (OSG::UInt16 button, OSG::Int16 x, OSG::Int16 y) { _mgr->mouseButtonRelease(button,x,y); }
293 void key (OSG::UChar8 cKey, OSG::Int16 x, OSG::Int16 y) { _mgr->key(cKey,x,y); }
295 void updateClipPlanes (const VecCPData& vec);
296 void createClipPlaneDetails ();
298 public:
299 static ClippingSceneManagerPtr
300 create (OSG::SimpleSceneManager* mgr);
302 ~ClippingSceneManager ();
303 private:
304 ClippingSceneManager (OSG::SimpleSceneManager* mgr);
306 void initialize ();
308 private:
309 void updateClipPlaneState (int numEnabled);
311 void createClipSubGraph (int i);
313 OSG::NodeTransitPtr createClipSubGraphPartFst (int i) const;
314 OSG::NodeTransitPtr createClipSubGraphPartSec (int i) const;
316 OSG::MaterialGroupTransitPtr create_mat_group_fst (int i) const;
317 OSG::MaterialGroupTransitPtr create_mat_group_sec (int i) const;
319 OSG::ChunkMaterialTransitPtr material_1 (int i) const;
320 OSG::ChunkMaterialTransitPtr material_2 (int i) const;
321 OSG::ChunkMaterialTransitPtr material_3 (std::size_t i) const;
323 OSG::NodeTransitPtr create_plane_node (OSG::MaterialGroup* mgrp_sec, int i) const;
325 private:
326 OSG::SimpleSceneManagerRefPtr _mgr;
327 OSG::ChunkMaterialRefPtr _overrideMaterial;
329 OSG::NodeRefPtr _root;
330 OSG::NodeRefPtr _internalRoot;
331 OSG::NodeRefPtr _clippingRoot;
332 OSG::NodeRefPtr _clipPlaneRoot;
334 OSG::ContainerCollectionRefPtr _container;
336 VecCPDetailsT _vecClipPlaneDetails;
337 VecCPData _vecClipPlaneDataLast;
340 //----- create ----------------------------------------------------------------
342 ClippingSceneManagerPtr
343 ClippingSceneManager::create(OSG::SimpleSceneManager* pMgr)
345 assert(pMgr);
346 return ClippingSceneManagerPtr(new ClippingSceneManager(pMgr));
349 //----- ctor ------------------------------------------------------------------
351 ClippingSceneManager::ClippingSceneManager(OSG::SimpleSceneManager* pMgr)
352 : _mgr(pMgr)
353 , _overrideMaterial(NULL)
354 , _root(NULL)
355 , _internalRoot(NULL)
356 , _clippingRoot(NULL)
357 , _clipPlaneRoot(NULL)
358 , _container(NULL)
359 , _vecClipPlaneDetails()
360 , _vecClipPlaneDataLast()
362 initialize();
365 //----- dtor ------------------------------------------------------------------
367 ClippingSceneManager::~ClippingSceneManager()
369 _vecClipPlaneDataLast.clear();
370 _vecClipPlaneDetails.clear();
372 _clipPlaneRoot = NULL;
373 _clippingRoot = NULL;
374 _internalRoot = NULL;
375 _root = NULL;
376 _overrideMaterial = NULL;
377 _mgr = NULL;
380 //----- setRoot ---------------------------------------------------------------
382 void ClippingSceneManager::setRoot(OSG::Node* root)
384 using namespace OSG;
386 if (_clippingRoot)
387 _internalRoot->subChild(_clippingRoot);
389 _clippingRoot = root;
391 if (_clippingRoot) {
392 setName(_clippingRoot, "_clippingRoot");
393 _internalRoot->addChild(_clippingRoot);
397 //----- initialize ------------------------------------------------------------
399 void ClippingSceneManager::initialize()
401 using namespace OSG;
403 _root = makeNodeFor(Group::create());
404 _internalRoot = makeNodeFor(Group::create());
405 _clippingRoot = makeNodeFor(Group::create());
406 _clipPlaneRoot = makeNodeFor(GroupingStage::create());
408 _overrideMaterial = ChunkMaterial::create();
410 MaterialChunkOverrideGroupUnrecPtr mat_grp = MaterialChunkOverrideGroup::create();
411 mat_grp->setMaterial(_overrideMaterial);
413 NodeUnrecPtr overrideNode = makeNodeFor(mat_grp);
415 _root->addChild(overrideNode);
416 _root->addChild(_clipPlaneRoot);
418 overrideNode->addChild(_internalRoot);
419 _internalRoot->addChild(_clippingRoot);
422 // for storing clipplane beacon we use a container
423 // collection attachment which we attach to the scene
424 // node. Otherwise the scene could not be saved correctly,
425 // as the beacons would be lost.
427 _container = ContainerCollection::create();
428 _root->addAttachment(_container);
431 // For each clip plane we provide a ClipPlaneChunk, the plane geometry,
432 // the plane transform core and at least a plane color conveniently in
433 // a vector of type VecCPDetailsT. The next function call
434 // initializes this data structure.
436 createClipPlaneDetails();
438 assert(_mgr->getWindow() != NULL);
440 _mgr->setRoot(_root);
443 // For illustration purpose only
445 setName(_root, "_root");
446 setName(_internalRoot, "_internalRoot");
447 setName(_clippingRoot , "_clippingRoot");
448 setName(_clipPlaneRoot, "_clipPlaneRoot");
449 setName(overrideNode, "overrideNode");
452 //----- createClipPlaneDetails ------------------------------------------------
454 void ClippingSceneManager::createClipPlaneDetails()
456 using namespace OSG;
458 for(int i = 0; i < iNumClipPlanes; ++i)
460 ClipPlaneDetails details;
463 // Create clip plane chunk
465 details._clipPlaneBeacon = Node::create();
466 details._clipPlaneBeacon->setCore(Transform::create());
468 _container->addContainer(details._clipPlaneBeacon);
470 details._clipPlaneChunk = ClipPlaneChunk::create();
471 details._clipPlaneChunk->setEquation(Vec4f(1,0,0,0));
472 details._clipPlaneChunk->setEnable(false);
473 details._clipPlaneChunk->setBeacon(details._clipPlaneBeacon);
476 // Create plane geometry
478 details._planeGeometryCore = makePlaneGeo(100.f, 100.f, 128, 128);
479 details._planeGeometryCore->setMaterial(NULL);
482 // Create plane transformation core
484 Matrix mat;
485 mat.setIdentity();
487 details._planeTrafoCore = Transform::create();
488 details._planeTrafoCore->setMatrix(mat);
491 // Define plane color
493 details._planeMaterialChunk = MaterialChunk::create();
494 details._planeMaterialChunk->setLit(true);
495 details._planeMaterialChunk->setDiffuse (planeCol[i]);
496 details._planeMaterialChunk->setSpecular (Color4f(0.8f, 0.8f, 0.8f, 1.0f));
497 details._planeMaterialChunk->setShininess(20);
499 details._planePolygonChunk = PolygonChunk::create();
500 details._planePolygonChunk->setFrontMode(GL_FILL);
501 details._planePolygonChunk->setBackMode(GL_FILL);
502 details._planePolygonChunk->setCullFace(GL_NONE);
504 _vecClipPlaneDetails.push_back(details);
506 setName(details._clipPlaneBeacon, "_clipPlaneBeacon");
510 //----- updateClipPlanes ------------------------------------------------------
512 void ClippingSceneManager::updateClipPlanes(const VecCPData& vec)
514 using namespace OSG;
516 std::size_t sz = vec.size();
517 int numEnabled = 0;
519 std::size_t num = _vecClipPlaneDetails.size();
520 for (std::size_t i = 0; i < num; ++i)
522 ClipPlaneChunk *clipPlaneChunk =
523 _vecClipPlaneDetails[i]._clipPlaneChunk;
525 clipPlaneChunk->setEnable(false);
527 if(i < sz)
529 const ClipPlaneData& data = vec[i];
532 // Update the clip plane chunk
534 clipPlaneChunk->setEquation(data._equation);
535 clipPlaneChunk->setEnable (data._enabled );
537 if (data._enabled)
538 numEnabled++;
541 // and the plane transform core
543 Matrix rotMat;
544 Vec4f v1(0.f, 0.f, -1.f, 0.f);
545 Quaternion q(Vec3f(v1), Vec3f(data._equation));
546 rotMat.setTransform(q);
548 Matrix mat;
549 Vec3f v2(0.0f, 0.0f, data._equation[3]);
550 mat.setTranslate(v2);
552 mat.multLeft(rotMat);
554 _vecClipPlaneDetails[i]._planeTrafoCore->setMatrix(mat);
558 bool update = _vecClipPlaneDataLast.size() != sz;
560 if (!update) {
561 for (std::size_t i = 0; i < sz; ++i) {
562 if (_vecClipPlaneDataLast[i]._enabled != vec[i]._enabled) {
563 update = true;
564 break;
569 if (update) {
570 updateClipPlaneState(numEnabled);
571 _vecClipPlaneDataLast = vec;
575 //----- updateClipPlaneState --------------------------------------------------
577 void ClippingSceneManager::updateClipPlaneState(int numEnabled)
579 using namespace OSG;
581 StateChunk* curr = _overrideMaterial->find(ClipPlaneChunk::getClassType());
582 while (curr) {
583 _overrideMaterial->subChunk(curr);
584 curr = _overrideMaterial->find(ClipPlaneChunk::getClassType());
587 if (numEnabled > 0)
589 _clipPlaneRoot->clearChildren();
591 std::size_t sz = _vecClipPlaneDetails.size();
592 for (std::size_t i = 0; i < sz; ++i)
594 ClipPlaneChunk* clipPlaneChunk = _vecClipPlaneDetails[i]._clipPlaneChunk;
595 if (clipPlaneChunk->getEnable())
597 _overrideMaterial->addChunk(clipPlaneChunk);
599 createClipSubGraph(static_cast<int>(i));
603 } else
604 _clipPlaneRoot->clearChildren();
606 commitChanges();
609 //----- createClipSubGraph ----------------------------------------------------
611 void ClippingSceneManager::createClipSubGraph(int i)
613 using namespace OSG;
615 NodeUnrecPtr node_1 = createClipSubGraphPartFst(i);
616 NodeUnrecPtr node_2 = createClipSubGraphPartSec(i);
618 _clipPlaneRoot->addChild(node_1);
619 _clipPlaneRoot->addChild(node_2);
621 setName(node_1, "clipSubGraphPartFst");
622 setName(node_2, "clipSubGraphPartSec");
625 //----- createClipSubGraphPartFst ---------------------------------------------
627 OSG::NodeTransitPtr ClippingSceneManager::createClipSubGraphPartFst(int i) const
629 using namespace OSG;
631 VisitSubTreeUnrecPtr visitor = VisitSubTree::create();
632 visitor->setSubTreeRoot(_internalRoot);
633 NodeUnrecPtr visit_node = makeNodeFor(visitor);
635 NodeUnrecPtr node = makeNodeFor( create_mat_group_fst(i) );
636 node->addChild(visit_node);
638 return NodeTransitPtr(node);
641 //----- createClipSubGraphPartSec ---------------------------------------------
643 OSG::NodeTransitPtr ClippingSceneManager::createClipSubGraphPartSec(int i) const
645 using namespace OSG;
647 MaterialGroupUnrecPtr mgrp = create_mat_group_sec(i);
648 return NodeTransitPtr(create_plane_node(mgrp, i));
651 //----- create_mat_group_fst --------------------------------------------------
653 OSG::MaterialGroupTransitPtr ClippingSceneManager::create_mat_group_fst(int i) const
655 using namespace OSG;
657 ChunkMaterialUnrecPtr mat1 = material_1(i);
658 ChunkMaterialUnrecPtr mat2 = material_2(i);
660 MultiPassMaterialUnrecPtr mat = MultiPassMaterial::create();
661 mat->addMaterial(mat1);
662 mat->addMaterial(mat2);
664 mat->setSortKey(2*i + 0);
666 setName(mat, "setSortKey(2*i + 0)");
668 MaterialGroupUnrecPtr mgrp = MaterialGroup::create();
669 mgrp->setMaterial(mat);
671 return MaterialGroupTransitPtr(mgrp);
674 //----- create_mat_group_sec --------------------------------------------------
676 OSG::MaterialGroupTransitPtr ClippingSceneManager::create_mat_group_sec(int i) const
678 using namespace OSG;
680 ChunkMaterialUnrecPtr mat = material_3(i);
682 mat->setSortKey(2*i + 1);
684 setName(mat, "setSortKey(2*i + 1)");
686 MaterialGroupUnrecPtr mgrp = MaterialGroup::create();
687 mgrp->setMaterial(mat);
689 return MaterialGroupTransitPtr(mgrp);
692 //----- create_plane_node -----------------------------------------------------
694 OSG::NodeTransitPtr ClippingSceneManager::create_plane_node(
695 OSG::MaterialGroup* mgrp,
696 int i) const
698 using namespace OSG;
700 NodeUnrecPtr planeGeoNode = Node::create();
701 planeGeoNode->setCore(_vecClipPlaneDetails[i]._planeGeometryCore);
703 NodeUnrecPtr planeTrafoNode = Node::create();
704 planeTrafoNode->setCore(_vecClipPlaneDetails[i]._planeTrafoCore);
705 planeTrafoNode->addChild(planeGeoNode);
707 NodeUnrecPtr materialNode = Node::create();
708 materialNode->setCore(mgrp);
709 materialNode->addChild(planeTrafoNode);
711 setName(planeGeoNode, "planeGeoNode");
712 setName(planeTrafoNode, "planeTrafoNode");
713 setName(materialNode, "planeMaterialNode");
715 return NodeTransitPtr(materialNode);
718 //----- material_1 ------------------------------------------------------------
720 OSG::ChunkMaterialTransitPtr ClippingSceneManager::material_1(int i) const
722 using namespace OSG;
724 StencilChunkUnrecPtr stencilChunk = StencilChunk::create();
725 stencilChunk->setClearBuffer(1);
726 stencilChunk->setStencilFunc(GL_ALWAYS);
727 stencilChunk->setStencilValue(0);
728 stencilChunk->setStencilMask(0x0);
729 stencilChunk->setStencilOpFail(GL_KEEP);
730 stencilChunk->setStencilOpZFail(GL_KEEP);
731 stencilChunk->setStencilOpZPass(GL_INCR);
733 setName(stencilChunk, "1 GL_ALWAYS\\n0 0x0n\\nGL_KEEP GL_KEEP GL_INCR");
735 DepthChunkUnrecPtr depthChunk = DepthChunk::create();
736 depthChunk->setEnable(false);
738 PolygonChunkUnrecPtr polygonChunk = PolygonChunk::create();
739 polygonChunk->setFrontMode(GL_FILL);
740 polygonChunk->setBackMode(GL_FILL);
741 polygonChunk->setCullFace(GL_FRONT);
743 ColorMaskChunkUnrecPtr colorMaskChunk = ColorMaskChunk::create();
744 colorMaskChunk->setMaskR(false);
745 colorMaskChunk->setMaskG(false);
746 colorMaskChunk->setMaskB(false);
747 colorMaskChunk->setMaskA(false);
749 setName(colorMaskChunk, "4xfalse");
751 ChunkMaterialUnrecPtr mat = ChunkMaterial::create();
752 mat->addChunk(stencilChunk);
753 mat->addChunk(depthChunk);
754 mat->addChunk(polygonChunk);
755 mat->addChunk(colorMaskChunk);
756 mat->addChunk(_vecClipPlaneDetails[i]._clipPlaneChunk);
758 return ChunkMaterialTransitPtr(mat);
761 //----- material_2 ------------------------------------------------------------
763 OSG::ChunkMaterialTransitPtr ClippingSceneManager::material_2(int i) const
765 using namespace OSG;
767 StencilChunkUnrecPtr stencilChunk = StencilChunk::create();
768 stencilChunk->setClearBuffer(0);
769 stencilChunk->setStencilFunc(GL_ALWAYS);
770 stencilChunk->setStencilValue(0);
771 stencilChunk->setStencilMask(0x0);
772 stencilChunk->setStencilOpFail(GL_KEEP);
773 stencilChunk->setStencilOpZFail(GL_KEEP);
774 stencilChunk->setStencilOpZPass(GL_DECR);
776 setName(stencilChunk, "0 GL_ALWAYS\\n0 0x0\\nGL_KEEP GL_KEEP GL_DECR");
778 DepthChunkUnrecPtr depthChunk = DepthChunk::create();
779 depthChunk->setEnable(false);
781 PolygonChunkUnrecPtr polygonChunk = PolygonChunk::create();
782 polygonChunk->setFrontMode(GL_FILL);
783 polygonChunk->setBackMode(GL_FILL);
784 polygonChunk->setCullFace(GL_BACK);
786 ColorMaskChunkUnrecPtr colorMaskChunk = ColorMaskChunk::create();
787 colorMaskChunk->setMaskR(false);
788 colorMaskChunk->setMaskG(false);
789 colorMaskChunk->setMaskB(false);
790 colorMaskChunk->setMaskA(false);
792 setName(colorMaskChunk, "4xfalse");
794 ChunkMaterialUnrecPtr mat = ChunkMaterial::create();
795 mat->addChunk(stencilChunk);
796 mat->addChunk(depthChunk);
797 mat->addChunk(polygonChunk);
798 mat->addChunk(colorMaskChunk);
799 mat->addChunk(_vecClipPlaneDetails[i]._clipPlaneChunk);
801 return ChunkMaterialTransitPtr(mat);
804 //----- material_3 ------------------------------------------------------------
806 OSG::ChunkMaterialTransitPtr ClippingSceneManager::material_3(std::size_t i) const
808 using namespace OSG;
810 StencilChunkUnrecPtr stencilChunk = StencilChunk::create();
811 stencilChunk->setClearBuffer(0);
812 stencilChunk->setStencilFunc(GL_NOTEQUAL);
813 stencilChunk->setStencilValue(0);
814 stencilChunk->setStencilMask(~0x0);
815 stencilChunk->setStencilOpFail(GL_KEEP);
816 stencilChunk->setStencilOpZFail(GL_KEEP);
817 stencilChunk->setStencilOpZPass(GL_KEEP);
819 setName(stencilChunk, "0 GL_NOTEQUAL\\n0 ~0x0\\nGL_KEEP GL_KEEP GL_KEEP");
821 ChunkMaterialUnrecPtr mat = ChunkMaterial::create();
823 mat->addChunk(_vecClipPlaneDetails[i]._planeMaterialChunk);
824 mat->addChunk(_vecClipPlaneDetails[i]._planePolygonChunk);
826 std::size_t sNumClipPlanes = _vecClipPlaneDetails.size();
827 for (std::size_t j = 0; j < sNumClipPlanes; ++j) {
828 if (i != j && _vecClipPlaneDetails[j]._clipPlaneChunk->getEnable())
829 mat->addChunk(_vecClipPlaneDetails[j]._clipPlaneChunk);
831 mat->addChunk(stencilChunk);
833 return ChunkMaterialTransitPtr(mat);
837 // scene management functions
840 /*----- create_and_exe_dot_file ---------------------------------------------*/
842 void create_and_exe_dot_file(OSG::Node* node)
844 using namespace OSG;
846 namespace fs = ::boost::filesystem;
848 fs::path dot_file(graphviz_output_file); dot_file.replace_extension(".dot");
849 fs::path png_file(graphviz_output_file); png_file.replace_extension(".png");
851 if (fs::exists(dot_file))
852 fs::remove(dot_file);
854 if (fs::exists(png_file))
855 fs::remove(png_file);
857 DotFileGeneratorGraphOpRefPtr go = DotFileGeneratorGraphOp::create();
859 std::string param("filename=");
860 go->setParams(param + dot_file.string());
861 go->setParams("max_node_children=10 no_name_attachments=true no_ranks=true");
863 go->traverse(node);
865 if (!fs::exists(dot_file))
866 return;
868 fs::path exe_file(graphviz_dot_executale);
869 if (!fs::exists(exe_file))
870 return;
872 std::string cmd = exe_file.string();
873 cmd += " -T png " + dot_file.string() + " -o " + png_file.string();
875 system(cmd.c_str()) ;
878 //----- cleanup ---------------------------------------------------------------
880 void cleanup(void)
882 vecGeometries.clear();
883 mgr.reset();
886 //----- display ---------------------------------------------------------------
888 void display(void)
890 // render
892 mgr->redraw();
894 // all done, swap
895 glutSwapBuffers();
898 //----- reshape ---------------------------------------------------------------
900 void reshape(int w, int h)
902 mgr->resize(w,h);
903 glutPostRedisplay();
906 //----- mouse -----------------------------------------------------------------
908 void mouse(int button, int state, int x, int y)
910 if (state)
911 mgr->mouseButtonRelease(button, x, y);
912 else
913 mgr->mouseButtonPress(button, x, y);
915 glutPostRedisplay();
918 //----- motion ----------------------------------------------------------------
920 void motion(int x, int y)
922 mgr->mouseMove(x, y);
923 glutPostRedisplay();
926 //----- keyboard --------------------------------------------------------------
928 void keyboard(unsigned char k, int, int)
930 static OSG::Real32 val0 = 0.f;
931 static OSG::Real32 val1 = 0.f;
933 static OSG::Real32 x1 = 0.f;
934 static OSG::Real32 y1 = 0.f;
935 static OSG::Real32 z1 = 0.f;
937 static OSG::Real32 x2 = 0.f;
938 static OSG::Real32 y2 = 0.f;
939 static OSG::Real32 z2 = 0.f;
941 switch(k)
943 case ' ':
945 OSG::SceneGraphPrinter sgp(mgr->getRoot());
946 sgp.printDownTree(std::cout);
948 break;
950 case '1': // enable/disable clip plane 0
952 vecClipPlaneData[0]._enabled = !vecClipPlaneData[0]._enabled;
953 mgr->updateClipPlanes(vecClipPlaneData);
955 break;
956 case '2': // enable/disable clip plane 1
958 vecClipPlaneData[1]._enabled = !vecClipPlaneData[1]._enabled;
959 mgr->updateClipPlanes(vecClipPlaneData);
961 break;
962 case '3': // enable/disable box geometry
964 if(vecGeometries[0] == NULL)
966 OSG::Matrix matrix;
967 OSG::Vec3f v(10.f, 0.f, 15.f);
968 matrix.setTranslate(v);
970 //OSG::NodeUnrecPtr boxTree = BuildGeometry(BOX_GEOMETRY, matrix, OSG::Color3f(0.0f, 0.6f, 0.7f));
971 OSG::NodeUnrecPtr boxTree = BuildProxyGeometry(BOX_GEOMETRY, matrix, OSG::Color3f(0.0f, 0.6f, 0.7f));
973 vecGeometries[0] = boxTree;
974 mgr->getRoot()->addChild(boxTree);
976 else
978 mgr->getRoot()->subChild(vecGeometries[0]);
979 vecGeometries[0] = NULL;
982 // mgr->showAll();
983 // mgr->redraw();
985 break;
986 case '4': // enable/disable torus geometry
988 if (vecGeometries[1] == NULL)
990 OSG::Matrix matrix;
991 OSG::Vec3f v( 0.f, 10.f, 0.f);
992 matrix.setTranslate(v);
994 OSG::NodeUnrecPtr torusTree = BuildGeometry(TORUS_GEOMETRY, matrix, OSG::Color3f(0.7f, 0.2f, 0.0f));
995 //OSG::NodeUnrecPtr torusTree = BuildProxyGeometry(TORUS_GEOMETRY, matrix, OSG::Color3f(0.7f, 0.2f, 0.0f));
997 vecGeometries[1] = torusTree;
998 mgr->getRoot()->addChild(torusTree);
1000 else
1002 mgr->getRoot()->subChild(vecGeometries[1]);
1003 vecGeometries[1] = NULL;
1006 // mgr->showAll();
1007 // mgr->redraw();
1009 break;
1011 case '5':
1013 OSG::SceneFileHandler::the()->write(mgr->getRoot(),
1014 "clipplane_model.osb", true);
1016 break;
1017 case 'n': // move clip plane 0 opposite to the normal direction of the plane
1019 val0 -= 0.2f;
1020 vecClipPlaneData[0]._equation[3] = val0;
1021 mgr->updateClipPlanes(vecClipPlaneData);
1023 break;
1024 case 'm': // move clip plane 0 in the normal direction of the plane
1026 val0 += 0.2f;
1027 vecClipPlaneData[0]._equation[3] = val0;
1028 mgr->updateClipPlanes(vecClipPlaneData);
1030 break;
1031 case ',': // move clip plane 1 opposite to the normal direction of the plane
1033 val1 -= 0.2f;
1034 vecClipPlaneData[1]._equation[3] = val1;
1035 mgr->updateClipPlanes(vecClipPlaneData);
1037 break;
1038 case '.': // move clip plane 1 in the normal direction of the plane
1040 val1 += 0.2f;
1041 vecClipPlaneData[1]._equation[3] = val1;
1042 mgr->updateClipPlanes(vecClipPlaneData);
1044 break;
1045 case 'q': // move box in -x direction
1047 x1 -= 0.2f;
1049 OSG::Matrix matrix;
1050 OSG::Vec3f v(10.f + x1, 0.f + y1, 15.f + z1);
1051 matrix.setTranslate(v);
1053 if(vecGeometries[0] != NULL)
1055 OSG::TransformRefPtr transformCore =
1056 dynamic_cast<OSG::Transform *>(vecGeometries[0]->getCore());
1058 transformCore->setMatrix(matrix);
1061 break;
1062 case 'w': // move box in +x direction
1064 x1 += 0.2f;
1066 OSG::Matrix matrix;
1067 OSG::Vec3f v(10.f + x1, 0.f + y1, 15.f + z1);
1068 matrix.setTranslate(v);
1070 if(vecGeometries[0] != NULL)
1072 OSG::TransformRefPtr transformCore =
1073 dynamic_cast<OSG::Transform *>(vecGeometries[0]->getCore());
1075 transformCore->setMatrix(matrix);
1078 break;
1079 case 'a': // move box in -y direction
1081 y1 -= 0.2f;
1083 OSG::Matrix matrix;
1084 OSG::Vec3f v(10.f + x1, 0.f + y1, 15.f + z1);
1085 matrix.setTranslate(v);
1087 if(vecGeometries[0] != NULL)
1089 OSG::TransformRefPtr transformCore =
1090 dynamic_cast<OSG::Transform *>(vecGeometries[0]->getCore());
1092 transformCore->setMatrix(matrix);
1095 break;
1096 case 's': // move box in +y direction
1098 y1 += 0.2f;
1100 OSG::Matrix matrix;
1101 OSG::Vec3f v(10.f + x1, 0.f + y1, 15.f + z1);
1102 matrix.setTranslate(v);
1104 if(vecGeometries[0] != NULL)
1106 OSG::TransformRefPtr transformCore =
1107 dynamic_cast<OSG::Transform *>(vecGeometries[0]->getCore());
1109 transformCore->setMatrix(matrix);
1112 break;
1113 case 'y': // move box in -z direction
1115 z1 -= 0.2f;
1117 OSG::Matrix matrix;
1118 OSG::Vec3f v(10.f + x1, 0.f + y1, 15.f + z1);
1119 matrix.setTranslate(v);
1121 if(vecGeometries[0] != NULL)
1123 OSG::TransformRefPtr transformCore =
1124 dynamic_cast<OSG::Transform *>(vecGeometries[0]->getCore());
1126 transformCore->setMatrix(matrix);
1129 break;
1130 case 'x': // move box in +z direction
1132 z1 += 0.2f;
1134 OSG::Matrix matrix;
1135 OSG::Vec3f v(10.f + x1, 0.f + y1, 15.f + z1);
1136 matrix.setTranslate(v);
1138 if(vecGeometries[0] != NULL)
1140 OSG::TransformRefPtr transformCore =
1141 dynamic_cast<OSG::Transform *>(vecGeometries[0]->getCore());
1143 transformCore->setMatrix(matrix);
1146 break;
1147 case 'e': // move torus in -x direction
1149 x2 -= 0.2f;
1151 OSG::Matrix matrix;
1152 OSG::Vec3f v( 0.f + x2, 10.f + y2, 0.f + z2);
1153 matrix.setTranslate(v);
1155 if(vecGeometries[1] != NULL)
1157 OSG::TransformRefPtr transformCore =
1158 dynamic_cast<OSG::Transform *>(vecGeometries[1]->getCore());
1160 transformCore->setMatrix(matrix);
1163 break;
1164 case 'r': // move torus in +x direction
1166 x2 += 0.2f;
1168 OSG::Matrix matrix;
1169 OSG::Vec3f v( 0.f + x2, 10.f + y2, 0.f + z2);
1170 matrix.setTranslate(v);
1172 if(vecGeometries[1] != NULL)
1174 OSG::TransformRefPtr transformCore =
1175 dynamic_cast<OSG::Transform *>(vecGeometries[1]->getCore());
1177 transformCore->setMatrix(matrix);
1180 break;
1181 case 'd': // move torus in -y direction
1183 y2 -= 0.2f;
1185 OSG::Matrix matrix;
1186 OSG::Vec3f v( 0.f + x2, 10.f + y2, 0.f + z2);
1187 matrix.setTranslate(v);
1189 if(vecGeometries[1] != NULL)
1191 OSG::TransformRefPtr transformCore =
1192 dynamic_cast<OSG::Transform *>(vecGeometries[1]->getCore());
1194 transformCore->setMatrix(matrix);
1197 break;
1198 case 'f': // move torus in +y direction
1200 y2 += 0.2f;
1202 OSG::Matrix matrix;
1203 OSG::Vec3f v( 0.f + x2, 10.f + y2, 0.f + z2);
1204 matrix.setTranslate(v);
1206 if(vecGeometries[1] != NULL)
1208 OSG::TransformRefPtr transformCore =
1209 dynamic_cast<OSG::Transform *>(vecGeometries[1]->getCore());
1211 transformCore->setMatrix(matrix);
1214 break;
1215 case 'c': // move torus in -z direction
1217 z2 -= 0.2f;
1219 OSG::Matrix matrix;
1220 OSG::Vec3f v( 0.f + x2, 10.f + y2, 0.f + z2);
1221 matrix.setTranslate(v);
1223 if(vecGeometries[1] != NULL)
1225 OSG::TransformRefPtr transformCore =
1226 dynamic_cast<OSG::Transform *>(vecGeometries[1]->getCore());
1228 transformCore->setMatrix(matrix);
1231 break;
1232 case 'v': // move torus in +z direction
1234 z2 += 0.2f;
1236 OSG::Matrix matrix;
1237 OSG::Vec3f v( 0.f + x2, 10.f + y2, 0.f + z2);
1238 matrix.setTranslate(v);
1240 if(vecGeometries[1] != NULL)
1242 OSG::TransformRefPtr transformCore =
1243 dynamic_cast<OSG::Transform *>(vecGeometries[1]->getCore());
1245 transformCore->setMatrix(matrix);
1248 break;
1250 case 'p': // create a png from scene with the graphviz tool output
1252 create_and_exe_dot_file(mgr->getInternalRoot());
1254 break;
1256 case 27:
1258 cleanup();
1260 OSG::osgExit();
1261 exit(0);
1263 break;
1266 glutPostRedisplay();
1269 //----- doMain ----------------------------------------------------------------
1271 int doMain(int argc, char **argv)
1274 // This might be necessary depending on the
1275 // used platform to ensure that the corresponding
1276 // libraries get loaded.
1278 OSG::preloadSharedObject("OSGFileIO");
1279 OSG::preloadSharedObject("OSGImageFileIO");
1280 OSG::preloadSharedObject("OSGContribPLY");
1282 OSG::osgInit(argc,argv);
1284 // GLUT init
1285 glutInit(&argc, argv);
1287 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_STENCIL | GLUT_DOUBLE);
1289 glutCreateWindow("OpenSG");
1291 glutReshapeFunc(reshape);
1292 glutDisplayFunc(display);
1293 glutIdleFunc(display);
1294 glutMouseFunc(mouse);
1295 glutMotionFunc(motion);
1296 glutKeyboardFunc(keyboard);
1298 OSG::PassiveWindowRefPtr pwin=OSG::PassiveWindow::create();
1299 pwin->init();
1301 // create the SimpleSceneManager helper
1302 OSG::SimpleSceneManagerRefPtr simple_mgr = OSG::SimpleSceneManager::create();
1304 // create the window and initial camera/viewport
1305 simple_mgr->setWindow(pwin);
1307 // and the clipplane extension
1308 mgr = ClippingSceneManager::create(simple_mgr);
1311 // The scene
1313 OSG::NodeUnrecPtr scene = makeNodeFor(OSG::Group::create());
1314 scene->setCore(OSG::Group::create());
1316 // tell the manager what to manage
1317 mgr->setRoot(scene);
1320 // A place for accessing the box and torus.
1322 vecGeometries.push_back(NULL);
1323 vecGeometries.push_back(NULL);
1326 // Build concrete clipping planes and update the clip plane details.
1328 ClipPlaneData data1;
1329 ClipPlaneData data2;
1331 data1._equation = OSG::Vec4f(0,0,1,0);
1332 data1._enabled = true;
1334 data2._equation = OSG::Vec4f(1,0,0,0);
1335 data2._enabled = false;
1337 vecClipPlaneData.push_back(data1);
1338 vecClipPlaneData.push_back(data2);
1340 keyboard('3',-1,-1);
1341 keyboard('4',-1,-1);
1343 mgr->updateClipPlanes(vecClipPlaneData);
1345 // show the whole scene
1346 mgr->showAll();
1347 mgr->redraw();
1349 pwin->dumpExtensions();
1351 return 0;
1354 //----- main ------------------------------------------------------------------
1356 int main(int argc, char *argv[])
1358 doMain(argc, argv);
1360 // GLUT main loop
1361 glutMainLoop();
1364 // Clean up the global held data
1366 cleanup();
1368 OSG::osgExit();
1370 return 0;