1 // OpenSG example: ClipPlaneCaps2
3 // Demonstrates the use of the ClipPlaneChunk, StencilChunk for capping of
6 // This example uses VisitSubTree cores in order to minimize the memory
7 // footprint and in order cleanly separate the scene from the clipping
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
15 // a) mouse => standard navigator
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
42 #include <boost/shared_ptr.hpp>
43 #include <boost/foreach.hpp>
44 #include <boost/filesystem.hpp>
46 #ifdef OSG_BUILD_ACTIVE
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
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
) };
121 typedef std::vector
<OSG::NodeRefPtr
> VecNodesT
;
124 // transport container for the actual clip plane data
128 OSG::Vec4f _equation
;
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
;
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
)
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 ---------------------------------------------------------
215 OSG::NodeTransitPtr
BuildGeometry(int kind
, const OSG::Matrix
& matrix
, const OSG::Color3f
& color
)
219 GeometryUnrecPtr geometryCore
= NULL
;
223 case TORUS_GEOMETRY
: geometryCore
= makeTorusGeo(2, 6, 8, 16); break;
224 case BOX_GEOMETRY
: geometryCore
= makeBoxGeo(15, 15, 15, 1, 1, 1); break;
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
)
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
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 ();
299 static ClippingSceneManagerPtr
300 create (OSG::SimpleSceneManager
* mgr
);
302 ~ClippingSceneManager ();
304 ClippingSceneManager (OSG::SimpleSceneManager
* mgr
);
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;
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
)
346 return ClippingSceneManagerPtr(new ClippingSceneManager(pMgr
));
349 //----- ctor ------------------------------------------------------------------
351 ClippingSceneManager::ClippingSceneManager(OSG::SimpleSceneManager
* pMgr
)
353 , _overrideMaterial(NULL
)
355 , _internalRoot(NULL
)
356 , _clippingRoot(NULL
)
357 , _clipPlaneRoot(NULL
)
359 , _vecClipPlaneDetails()
360 , _vecClipPlaneDataLast()
365 //----- dtor ------------------------------------------------------------------
367 ClippingSceneManager::~ClippingSceneManager()
369 _vecClipPlaneDataLast
.clear();
370 _vecClipPlaneDetails
.clear();
372 _clipPlaneRoot
= NULL
;
373 _clippingRoot
= NULL
;
374 _internalRoot
= NULL
;
376 _overrideMaterial
= NULL
;
380 //----- setRoot ---------------------------------------------------------------
382 void ClippingSceneManager::setRoot(OSG::Node
* root
)
387 _internalRoot
->subChild(_clippingRoot
);
389 _clippingRoot
= root
;
392 setName(_clippingRoot
, "_clippingRoot");
393 _internalRoot
->addChild(_clippingRoot
);
397 //----- initialize ------------------------------------------------------------
399 void ClippingSceneManager::initialize()
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()
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
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
)
516 std::size_t sz
= vec
.size();
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);
529 const ClipPlaneData
& data
= vec
[i
];
532 // Update the clip plane chunk
534 clipPlaneChunk
->setEquation(data
._equation
);
535 clipPlaneChunk
->setEnable (data
._enabled
);
541 // and the plane transform core
544 Vec4f
v1(0.f
, 0.f
, -1.f
, 0.f
);
545 Quaternion
q(Vec3f(v1
), Vec3f(data
._equation
));
546 rotMat
.setTransform(q
);
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
;
561 for (std::size_t i
= 0; i
< sz
; ++i
) {
562 if (_vecClipPlaneDataLast
[i
]._enabled
!= vec
[i
]._enabled
) {
570 updateClipPlaneState(numEnabled
);
571 _vecClipPlaneDataLast
= vec
;
575 //----- updateClipPlaneState --------------------------------------------------
577 void ClippingSceneManager::updateClipPlaneState(int numEnabled
)
581 StateChunk
* curr
= _overrideMaterial
->find(ClipPlaneChunk::getClassType());
583 _overrideMaterial
->subChunk(curr
);
584 curr
= _overrideMaterial
->find(ClipPlaneChunk::getClassType());
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
));
604 _clipPlaneRoot
->clearChildren();
609 //----- createClipSubGraph ----------------------------------------------------
611 void ClippingSceneManager::createClipSubGraph(int i
)
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
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
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
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
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
,
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
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
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
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
)
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");
865 if (!fs::exists(dot_file
))
868 fs::path
exe_file(graphviz_dot_executale
);
869 if (!fs::exists(exe_file
))
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 ---------------------------------------------------------------
882 vecGeometries
.clear();
886 //----- display ---------------------------------------------------------------
898 //----- reshape ---------------------------------------------------------------
900 void reshape(int w
, int h
)
906 //----- mouse -----------------------------------------------------------------
908 void mouse(int button
, int state
, int x
, int y
)
911 mgr
->mouseButtonRelease(button
, x
, y
);
913 mgr
->mouseButtonPress(button
, x
, y
);
918 //----- motion ----------------------------------------------------------------
920 void motion(int x
, int y
)
922 mgr
->mouseMove(x
, y
);
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
;
945 OSG::SceneGraphPrinter
sgp(mgr
->getRoot());
946 sgp
.printDownTree(std::cout
);
950 case '1': // enable/disable clip plane 0
952 vecClipPlaneData
[0]._enabled
= !vecClipPlaneData
[0]._enabled
;
953 mgr
->updateClipPlanes(vecClipPlaneData
);
956 case '2': // enable/disable clip plane 1
958 vecClipPlaneData
[1]._enabled
= !vecClipPlaneData
[1]._enabled
;
959 mgr
->updateClipPlanes(vecClipPlaneData
);
962 case '3': // enable/disable box geometry
964 if(vecGeometries
[0] == NULL
)
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
);
978 mgr
->getRoot()->subChild(vecGeometries
[0]);
979 vecGeometries
[0] = NULL
;
986 case '4': // enable/disable torus geometry
988 if (vecGeometries
[1] == NULL
)
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
);
1002 mgr
->getRoot()->subChild(vecGeometries
[1]);
1003 vecGeometries
[1] = NULL
;
1013 OSG::SceneFileHandler::the()->write(mgr
->getRoot(),
1014 "clipplane_model.osb", true);
1017 case 'n': // move clip plane 0 opposite to the normal direction of the plane
1020 vecClipPlaneData
[0]._equation
[3] = val0
;
1021 mgr
->updateClipPlanes(vecClipPlaneData
);
1024 case 'm': // move clip plane 0 in the normal direction of the plane
1027 vecClipPlaneData
[0]._equation
[3] = val0
;
1028 mgr
->updateClipPlanes(vecClipPlaneData
);
1031 case ',': // move clip plane 1 opposite to the normal direction of the plane
1034 vecClipPlaneData
[1]._equation
[3] = val1
;
1035 mgr
->updateClipPlanes(vecClipPlaneData
);
1038 case '.': // move clip plane 1 in the normal direction of the plane
1041 vecClipPlaneData
[1]._equation
[3] = val1
;
1042 mgr
->updateClipPlanes(vecClipPlaneData
);
1045 case 'q': // move box in -x direction
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
);
1062 case 'w': // move box in +x direction
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
);
1079 case 'a': // move box in -y direction
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
);
1096 case 's': // move box in +y direction
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
);
1113 case 'y': // move box in -z direction
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
);
1130 case 'x': // move box in +z direction
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
);
1147 case 'e': // move torus in -x direction
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
);
1164 case 'r': // move torus in +x direction
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
);
1181 case 'd': // move torus in -y direction
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
);
1198 case 'f': // move torus in +y direction
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
);
1215 case 'c': // move torus in -z direction
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
);
1232 case 'v': // move torus in +z direction
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
);
1250 case 'p': // create a png from scene with the graphviz tool output
1252 create_and_exe_dot_file(mgr
->getInternalRoot());
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
);
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();
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
);
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
1349 pwin
->dumpExtensions();
1354 //----- main ------------------------------------------------------------------
1356 int main(int argc
, char *argv
[])
1364 // Clean up the global held data