1 // OpenSG example: ClipPlaneCaps
3 // Demonstrates the use of the ClipPlaneChunk, StencilChunk for capping of
6 // This examples allows creation of a box and a torus. Additionally, two clip
7 // planes can be set up. On clipping the geometry caps are used to repair the
11 // a) mouse => standard navigator
13 // '1': enable/disable clip plane 0
14 // '2': enable/disable clip plane 1
15 // '3': enable/disable box geometry
16 // '4': enable/disable torus geometry
17 // 'n': move clip plane 0 opposite to the normal direction of the plane
18 // 'm': move clip plane 0 in the normal direction of the plane
19 // ',': move clip plane 1 opposite to the normal direction of the plane
20 // '.': move clip plane 1 in the normal direction of the plane
21 // 'q': move box in -x direction
22 // 'w': move box in +x direction
23 // 'a': move box in -y direction
24 // 's': move box in +y direction
25 // 'y': move box in -z direction
26 // 'x': move box in +z direction
27 // 'e': move torus in -x direction
28 // 'r': move torus in +x direction
29 // 'd': move torus in -y direction
30 // 'f': move torus in +y direction
31 // 'c': move torus in -z direction
32 // 'v': move torus in +z direction
34 // This example was contributed by Johannes Brunen
38 #ifdef OSG_BUILD_ACTIVE
41 #include <OSGConfig.h>
42 #include <OSGSimpleGeometry.h>
43 #include <OSGPassiveWindow.h>
44 #include <OSGSimpleSceneManager.h>
45 #include <OSGSceneFileHandler.h>
47 #include <OSGMultiSwitch.h>
48 #include <OSGMaterialGroup.h>
49 #include <OSGGroupingStage.h>
50 #include <OSGChunkMaterial.h>
51 #include <OSGSimpleMaterial.h>
52 #include <OSGClipPlaneChunk.h>
53 #include <OSGStencilChunk.h>
54 #include <OSGInverseTransform.h>
55 #include <OSGPassiveBackground.h>
56 #include <OSGFieldContainerUtils.h>
57 #include <OSGSceneGraphUtils.h>
58 #include <OSGContainerCollection.h>
60 #else // OSG_BUILD_ACTIVE
62 #include <OpenSG/OSGGLUT.h>
63 #include <OpenSG/OSGConfig.h>
64 #include <OpenSG/OSGSimpleGeometry.h>
65 #include <OpenSG/OSGPassiveWindow.h>
66 #include <OpenSG/OSGSimpleSceneManager.h>
67 #include <OpenSG/OSGSceneFileHandler.h>
69 #include <OpenSG/OSGMultiSwitch.h>
70 #include <OpenSG/OSGMaterialGroup.h>
71 #include <OpenSG/OSGGroupingStage.h>
72 #include <OpenSG/OSGChunkMaterial.h>
73 #include <OpenSG/OSGSimpleMaterial.h>
74 #include <OpenSG/OSGClipPlaneChunk.h>
75 #include <OpenSG/OSGStencilChunk.h>
76 #include <OpenSG/OSGInverseTransform.h>
77 #include <OpenSG/OSGPassiveBackground.h>
78 #include <OpenSG/OSGFieldContainerUtils.h>
79 #include <OpenSG/OSGSceneGraphUtils.h>
80 #include <OpenSG/OSGContainerCollection.h>
82 #endif // OSG_BUILD_ACTIVE
85 typedef std::vector
<OSG::NodeRefPtr
> VecNodesT
; // convenience type
88 // transport container for the actual clip plane data
95 ClipPlaneData(void) : _equation(), _enabled(false) {}
98 typedef std::vector
<ClipPlaneData
> VecClipPlaneData
;
101 // for each clip plane these data are necessary
103 struct ClipPlaneDetails
105 OSG::ClipPlaneChunkRefPtr _clipPlaneChunk
;
106 OSG::GeometryRefPtr _planeGeometryCore
;
107 OSG::TransformRefPtr _planeTrafoCore
;
108 OSG::NodeRefPtr _planeBeaconNode
;
109 OSG::Color3f _planeColor
;
111 ClipPlaneDetails(void):
112 _clipPlaneChunk (NULL
),
113 _planeGeometryCore(NULL
),
114 _planeTrafoCore (NULL
),
115 _planeBeaconNode (NULL
),
121 typedef std::vector
<ClipPlaneDetails
> VecClipPlaneDetailsT
;
126 VecClipPlaneData vecClipPlaneData
; // transport clip plane info
127 VecClipPlaneDetailsT vecClipPlaneDetails
; // opensg clip plane state
128 VecNodesT vecGeometries
; // box and torus
130 OSG::SimpleSceneManagerRefPtr mgr
;
131 OSG::NodeRefPtr scene
;
132 OSG::ContainerCollectionRefPtr container
;
135 // the number of clipping planes supported by the demo. Define a plane color
138 const int iNumClipPlanes
= 2;
139 OSG::Color3f planeCol
[iNumClipPlanes
] = { OSG::Color3f(0,1,0),
140 OSG::Color3f(0,0,1) };
143 // Build the global clip plane state
145 void createClipPlaneDetails(void)
147 for(int i
= 0; i
< iNumClipPlanes
; ++i
)
149 ClipPlaneDetails details
;
152 // Create clip plane chunk
154 details
._planeBeaconNode
= OSG::Node::create();
155 details
._planeBeaconNode
->setCore(OSG::Transform::create());
157 container
->addContainer(details
._planeBeaconNode
);
159 details
._clipPlaneChunk
= OSG::ClipPlaneChunk::create();
160 details
._clipPlaneChunk
->setEquation(OSG::Vec4f(1,0,0,0));
161 details
._clipPlaneChunk
->setEnable(false);
162 details
._clipPlaneChunk
->setBeacon(details
._planeBeaconNode
);
166 // Create plane geometry
168 details
._planeGeometryCore
= OSG::makePlaneGeo(100.f
, 100.f
, 128, 128);
171 // Create plane transformation core
176 details
._planeTrafoCore
= OSG::Transform::create();
177 details
._planeTrafoCore
->setMatrix(mat
);
180 // Define plane color
182 details
._planeColor
= planeCol
[i
];
184 vecClipPlaneDetails
.push_back(details
);
193 vecClipPlaneDetails
.clear();
194 vecGeometries
.clear();
203 // In case the clip plane data change this function is called
205 void updateClipPlanes(const VecClipPlaneData
& vec
)
209 for(int i
= 0; i
< iNumClipPlanes
; ++i
)
211 OSG::ClipPlaneChunk
*clipPlaneChunk
=
212 vecClipPlaneDetails
[i
]._clipPlaneChunk
;
214 clipPlaneChunk
->setEnable(false);
218 const ClipPlaneData
& data
= vec
[i
];
221 // Update the clip plane chunk
223 clipPlaneChunk
->setEquation(data
._equation
);
224 clipPlaneChunk
->setEnable (data
._enabled
);
227 // and the plane transform core
230 OSG::Vec4f
v1(0.f
, 0.f
, -1.f
, 0.f
);
231 OSG::Quaternion
q(OSG::Vec3f(v1
), OSG::Vec3f(data
._equation
));
232 rotMat
.setTransform(q
);
235 OSG::Vec3f
v2(0.0f
, 0.0f
, data
._equation
[3]);
236 mat
.setTranslate(v2
);
238 mat
.multLeft(rotMat
);
240 vecClipPlaneDetails
[i
]._planeTrafoCore
->setMatrix(mat
);
246 // build geometry scenegraph Tree
249 // We need 3 material groups for the clip plane capping trick:
253 // +--------------------+--------------------+
255 // group1 (mat1) group2 (mat2) group3 (mat3)
257 // geometry (geo1) geometry (geo2) geometry (geo1)
259 // geo1 : actual geometry to draw
260 // geo2 : plane geometry coincident with the clip plane
262 // mat1 : has a stencil chunk that clears the stencil buffer first, than
263 // does the inversion, and has a clip plane chunk that enables one
264 // clip plane. Sort key 2*i + 0 with i idx of a clip plane.
265 // mat2 : has a stencil chunk and settings for drawing the clip plane
266 // geometry. All clip planes but the one coincident with the plane
267 // are activated. Sort key 2*i + 0 with i idx of a clip plane.
268 // mat3 : the material used for the actual geometry. All clip planes are
269 // activated. Sort key none.
271 // For each active clip plane copies of the left two branches need to be
274 OSG::NodeTransitPtr
buildGeoTree( OSG::Node
*pScene
,
276 const OSG::Matrix
&matrix
)
279 // Parent nodes for the left two branches
281 VecNodesT vecMaterialNodes1
;
282 VecNodesT vecMaterialNodes2
;
284 for(int i
= 0; i
< iNumClipPlanes
; ++i
) // foreach clip plane
287 // Branch 1: Imprint the geometry clip plane intersection into the
290 OSG::NodeRefPtr geomNode
= OSG::Node::create();
291 geomNode
->setCore(geo1
);
293 OSG::NodeRefPtr materialNode1
= OSG::Node::create();
295 // Create stencil material core
297 OSG::StencilChunkRefPtr stencilChunk1
= OSG::StencilChunk::create();
298 stencilChunk1
->setClearBuffer(1);
299 stencilChunk1
->setStencilFunc(GL_NEVER
);
300 stencilChunk1
->setStencilValue(1);
301 stencilChunk1
->setStencilMask(1);
302 stencilChunk1
->setStencilOpFail(GL_INVERT
);
303 stencilChunk1
->setStencilOpZFail(GL_INVERT
);
304 stencilChunk1
->setStencilOpZPass(GL_INVERT
);
306 OSG::ChunkMaterialRefPtr mat1
= OSG::ChunkMaterial::create();
307 mat1
->addChunk(stencilChunk1
);
308 mat1
->addChunk(vecClipPlaneDetails
[i
]._clipPlaneChunk
);
309 mat1
->setSortKey(2 * i
+ 0);
311 OSG::MaterialGroupRefPtr mgrp1
= OSG::MaterialGroup::create();
312 mgrp1
->setMaterial(mat1
);
314 materialNode1
->setCore(mgrp1
);
315 materialNode1
->addChild(geomNode
); // the primary geometry
317 vecMaterialNodes1
.push_back(materialNode1
);
320 // Branch 2: Draw plane at places were the stencil buffer is set
322 OSG::NodeRefPtr materialNode2
= OSG::Node ::create();
323 OSG::StencilChunkRefPtr stencilChunk2
= OSG::StencilChunk::create();
325 stencilChunk2
->setStencilFunc(GL_EQUAL
);
326 stencilChunk2
->setStencilValue(1);
327 stencilChunk2
->setStencilMask(1);
328 stencilChunk2
->setStencilOpFail(GL_KEEP
);
329 stencilChunk2
->setStencilOpZFail(GL_ZERO
);
330 stencilChunk2
->setStencilOpZPass(GL_ZERO
);
332 OSG::SimpleMaterialRefPtr mat2
= OSG::SimpleMaterial::create();
333 mat2
->setDiffuse(vecClipPlaneDetails
[i
]._planeColor
);
334 mat2
->setSpecular(OSG::Color3f(1,1,1));
338 // Do clip the plane with all clip planes but the one coincident
341 for(int j
= 0; j
< iNumClipPlanes
; ++j
)
345 mat2
->addChunk(vecClipPlaneDetails
[j
]._clipPlaneChunk
);
348 mat2
->addChunk(stencilChunk2
);
349 mat2
->setSortKey(2 * i
+ 1);
351 OSG::NodeRefPtr planeGeoNode
= OSG::Node::create();
352 planeGeoNode
->setCore(vecClipPlaneDetails
[i
]._planeGeometryCore
);
354 OSG::NodeRefPtr planeTrafoNode
= OSG::Node::create();
355 planeTrafoNode
->setCore(vecClipPlaneDetails
[i
]._planeTrafoCore
);
356 planeTrafoNode
->addChild(planeGeoNode
);
359 // Neutralize the summed up transformation at this point in the
360 // scenegraph since we are describing the plane in the same frame
361 // as the clip planes, i.e. world coordinates.
363 OSG::NodeRefPtr planeRootNode
= OSG::Node::create();
364 planeRootNode
->setCore(OSG::InverseTransform::create());
365 planeRootNode
->addChild(planeTrafoNode
);
367 OSG::MaterialGroupRefPtr mgrp2
= OSG::MaterialGroup::create();
368 mgrp2
->setMaterial(mat2
);
370 materialNode2
->setCore(mgrp2
);
371 materialNode2
->addChild(planeRootNode
); // plane geometry
373 vecMaterialNodes2
.push_back(materialNode2
);
377 // Finally, set up a branch for drawing the primary geometry
379 OSG::NodeRefPtr materialNode3
= OSG::Node ::create();
380 OSG::SimpleMaterialRefPtr mat3
= OSG::SimpleMaterial::create();
382 mat3
->setDiffuse(OSG::Color3f(1,0,0));
383 mat3
->setSpecular(OSG::Color3f(1,1,1));
387 // Clip the geometry with each clip plane
389 for(int i
= 0; i
< iNumClipPlanes
; ++i
)\
391 mat3
->addChunk(vecClipPlaneDetails
[i
]._clipPlaneChunk
);
394 OSG::MaterialGroupRefPtr mgrp3
= OSG::MaterialGroup::create();
395 mgrp3
->setMaterial(mat3
);
397 OSG::NodeRefPtr geometryNode
= OSG::Node::create();
398 geometryNode
->setCore(geo1
);
400 materialNode3
->setCore (mgrp3
);
401 materialNode3
->addChild(geometryNode
);
404 // The grouping stage core does suppress a reordering
405 // of the render states. This is necessary because the
406 // stencil states must be rendered in correct order.
407 // There is no state sorting across stages, so that
408 // would ensure that everything below a stage is rendered
409 // together and the sort key can enforce the right order
410 // among those things.
412 OSG::NodeRefPtr stageNode
= OSG::Node::create();
413 stageNode
->setCore(OSG::GroupingStage::create());
415 OSG::NodeRefPtr clipPlanePartNode
= OSG::Node::create();
416 clipPlanePartNode
->setCore(OSG::Group::create());
417 stageNode
->addChild(clipPlanePartNode
);
419 for(int i
= 0; i
< iNumClipPlanes
; ++i
)
421 clipPlanePartNode
->addChild(vecMaterialNodes1
[i
]);
422 clipPlanePartNode
->addChild(vecMaterialNodes2
[i
]);
426 // The multi switch core is not actually used in this
427 // example. However it could be used to define multiple
428 // render branches and selectively activate and deactivate
429 // them in a given context.
431 OSG::MultiSwitchRefPtr selectCore
= OSG::MultiSwitch::create();
432 selectCore
->setSwitchMode(OSG::MultiSwitch::ALL
);
435 // Add the branches to some parent node.
437 OSG::NodeRefPtr selectNode
= OSG::Node::create();
438 selectNode
->setCore(selectCore
);
440 selectNode
->addChild(stageNode
);
441 selectNode
->addChild(materialNode3
);
444 // Finally, the geometry should be transformable
446 OSG::TransformRefPtr transfCore
;
447 OSG::NodeRefPtr transfNode
=
448 OSG::makeCoredNode
<OSG::Transform
>(&transfCore
);
450 transfCore
->setMatrix(matrix
);
451 transfNode
->addChild(selectNode
); // if using sort keys use this
452 // instead of the former line.
454 return OSG::NodeTransitPtr(transfNode
);
471 // react to size changes
473 void reshape(int w
, int h
)
479 // react to mouse button presses
480 void mouse(int button
, int state
, int x
, int y
)
483 mgr
->mouseButtonRelease(button
, x
, y
);
485 mgr
->mouseButtonPress(button
, x
, y
);
491 // react to mouse motions with pressed buttons
493 void motion(int x
, int y
)
495 mgr
->mouseMove(x
, y
);
502 void keyboard(unsigned char k
, int, int)
504 static OSG::Real32 val0
= 0.f
;
505 static OSG::Real32 val1
= 0.f
;
507 static OSG::Real32 x1
= 0.f
;
508 static OSG::Real32 y1
= 0.f
;
509 static OSG::Real32 z1
= 0.f
;
511 static OSG::Real32 x2
= 0.f
;
512 static OSG::Real32 y2
= 0.f
;
513 static OSG::Real32 z2
= 0.f
;
519 OSG::SceneGraphPrinter
sgp(mgr
->getRoot());
520 sgp
.printDownTree(std::cout
);
524 case '1': // enable/disable clip plane 0
526 vecClipPlaneData
[0]._enabled
= !vecClipPlaneData
[0]._enabled
;
527 updateClipPlanes(vecClipPlaneData
);
530 case '2': // enable/disable clip plane 1
532 vecClipPlaneData
[1]._enabled
= !vecClipPlaneData
[1]._enabled
;
533 updateClipPlanes(vecClipPlaneData
);
536 case '3': // enable/disable box geometry
538 if(vecGeometries
[0] == NULL
)
541 OSG::Vec3f
v(10.f
, 0.f
, 15.f
);
542 matrix
.setTranslate(v
);
544 OSG::GeometryRefPtr boxGeo
=
545 OSG::makeBoxGeo(15, 15, 15, 1, 1, 1);
547 OSG::NodeRefPtr boxTree
= buildGeoTree(scene
,
551 vecGeometries
[0] = boxTree
;
552 scene
->addChild(boxTree
);
556 scene
->subChild(vecGeometries
[0]);
557 vecGeometries
[0] = NULL
;
564 case '4': // enable/disable torus geometry
566 if (vecGeometries
[1] == NULL
)
569 OSG::Vec3f
v( 0.f
, 10.f
, 0.f
);
570 matrix
.setTranslate(v
);
572 OSG::GeometryRefPtr torusGeo
= OSG::makeTorusGeo(2, 6, 8, 16);
573 OSG::NodeRefPtr torusTree
= buildGeoTree(scene
,
576 vecGeometries
[1] = torusTree
;
577 scene
->addChild(torusTree
);
581 scene
->subChild(vecGeometries
[1]);
582 vecGeometries
[1] = NULL
;
592 OSG::SceneFileHandler::the()->write(mgr
->getRoot(),
593 "clipplane_model.osb", true);
596 case 'n': // move clip plane 0 opposite to the normal direction of the plane
599 vecClipPlaneData
[0]._equation
[3] = val0
;
600 updateClipPlanes(vecClipPlaneData
);
603 case 'm': // move clip plane 0 in the normal direction of the plane
606 vecClipPlaneData
[0]._equation
[3] = val0
;
607 updateClipPlanes(vecClipPlaneData
);
610 case ',': // move clip plane 1 opposite to the normal direction of the plane
613 vecClipPlaneData
[1]._equation
[3] = val1
;
614 updateClipPlanes(vecClipPlaneData
);
617 case '.': // move clip plane 1 in the normal direction of the plane
620 vecClipPlaneData
[1]._equation
[3] = val1
;
621 updateClipPlanes(vecClipPlaneData
);
624 case 'q': // move box in -x direction
629 OSG::Vec3f
v(10.f
+ x1
, 0.f
+ y1
, 15.f
+ z1
);
630 matrix
.setTranslate(v
);
632 if(vecGeometries
[0] != NULL
)
634 OSG::TransformRefPtr transformCore
=
635 dynamic_cast<OSG::Transform
*>(vecGeometries
[0]->getCore());
637 transformCore
->setMatrix(matrix
);
641 case 'w': // move box in +x direction
646 OSG::Vec3f
v(10.f
+ x1
, 0.f
+ y1
, 15.f
+ z1
);
647 matrix
.setTranslate(v
);
649 if(vecGeometries
[0] != NULL
)
651 OSG::TransformRefPtr transformCore
=
652 dynamic_cast<OSG::Transform
*>(vecGeometries
[0]->getCore());
654 transformCore
->setMatrix(matrix
);
658 case 'a': // move box in -y direction
663 OSG::Vec3f
v(10.f
+ x1
, 0.f
+ y1
, 15.f
+ z1
);
664 matrix
.setTranslate(v
);
666 if(vecGeometries
[0] != NULL
)
668 OSG::TransformRefPtr transformCore
=
669 dynamic_cast<OSG::Transform
*>(vecGeometries
[0]->getCore());
671 transformCore
->setMatrix(matrix
);
675 case 's': // move box in +y direction
680 OSG::Vec3f
v(10.f
+ x1
, 0.f
+ y1
, 15.f
+ z1
);
681 matrix
.setTranslate(v
);
683 if(vecGeometries
[0] != NULL
)
685 OSG::TransformRefPtr transformCore
=
686 dynamic_cast<OSG::Transform
*>(vecGeometries
[0]->getCore());
688 transformCore
->setMatrix(matrix
);
692 case 'y': // move box in -z direction
697 OSG::Vec3f
v(10.f
+ x1
, 0.f
+ y1
, 15.f
+ z1
);
698 matrix
.setTranslate(v
);
700 if(vecGeometries
[0] != NULL
)
702 OSG::TransformRefPtr transformCore
=
703 dynamic_cast<OSG::Transform
*>(vecGeometries
[0]->getCore());
705 transformCore
->setMatrix(matrix
);
709 case 'x': // move box in +z direction
714 OSG::Vec3f
v(10.f
+ x1
, 0.f
+ y1
, 15.f
+ z1
);
715 matrix
.setTranslate(v
);
717 if(vecGeometries
[0] != NULL
)
719 OSG::TransformRefPtr transformCore
=
720 dynamic_cast<OSG::Transform
*>(vecGeometries
[0]->getCore());
722 transformCore
->setMatrix(matrix
);
726 case 'e': // move torus in -x direction
731 OSG::Vec3f
v( 0.f
+ x2
, 10.f
+ y2
, 0.f
+ z2
);
732 matrix
.setTranslate(v
);
734 if(vecGeometries
[1] != NULL
)
736 OSG::TransformRefPtr transformCore
=
737 dynamic_cast<OSG::Transform
*>(vecGeometries
[1]->getCore());
739 transformCore
->setMatrix(matrix
);
743 case 'r': // move torus in +x direction
748 OSG::Vec3f
v( 0.f
+ x2
, 10.f
+ y2
, 0.f
+ z2
);
749 matrix
.setTranslate(v
);
751 if(vecGeometries
[1] != NULL
)
753 OSG::TransformRefPtr transformCore
=
754 dynamic_cast<OSG::Transform
*>(vecGeometries
[1]->getCore());
756 transformCore
->setMatrix(matrix
);
760 case 'd': // move torus in -y direction
765 OSG::Vec3f
v( 0.f
+ x2
, 10.f
+ y2
, 0.f
+ z2
);
766 matrix
.setTranslate(v
);
768 if(vecGeometries
[1] != NULL
)
770 OSG::TransformRefPtr transformCore
=
771 dynamic_cast<OSG::Transform
*>(vecGeometries
[1]->getCore());
773 transformCore
->setMatrix(matrix
);
777 case 'f': // move torus in +y direction
782 OSG::Vec3f
v( 0.f
+ x2
, 10.f
+ y2
, 0.f
+ z2
);
783 matrix
.setTranslate(v
);
785 if(vecGeometries
[1] != NULL
)
787 OSG::TransformRefPtr transformCore
=
788 dynamic_cast<OSG::Transform
*>(vecGeometries
[1]->getCore());
790 transformCore
->setMatrix(matrix
);
794 case 'c': // move torus in -z direction
799 OSG::Vec3f
v( 0.f
+ x2
, 10.f
+ y2
, 0.f
+ z2
);
800 matrix
.setTranslate(v
);
802 if(vecGeometries
[1] != NULL
)
804 OSG::TransformRefPtr transformCore
=
805 dynamic_cast<OSG::Transform
*>(vecGeometries
[1]->getCore());
807 transformCore
->setMatrix(matrix
);
811 case 'v': // move torus in +z direction
816 OSG::Vec3f
v( 0.f
+ x2
, 10.f
+ y2
, 0.f
+ z2
);
817 matrix
.setTranslate(v
);
819 if(vecGeometries
[1] != NULL
)
821 OSG::TransformRefPtr transformCore
=
822 dynamic_cast<OSG::Transform
*>(vecGeometries
[1]->getCore());
824 transformCore
->setMatrix(matrix
);
841 int doMain(int argc
, char **argv
)
844 // This might be necessary depending on the
845 // used platform to ensure that the corresponding
846 // libraries get loaded.
848 OSG::preloadSharedObject("OSGFileIO");
849 OSG::preloadSharedObject("OSGImageFileIO");
850 OSG::preloadSharedObject("OSGContribPLY");
852 OSG::osgInit(argc
,argv
);
855 glutInit(&argc
, argv
);
857 glutInitDisplayMode(GLUT_RGB
| GLUT_DEPTH
| GLUT_STENCIL
| GLUT_DOUBLE
);
859 glutCreateWindow("OpenSG");
861 glutReshapeFunc(reshape
);
862 glutDisplayFunc(display
);
863 glutIdleFunc(display
);
864 glutMouseFunc(mouse
);
865 glutMotionFunc(motion
);
866 glutKeyboardFunc(keyboard
);
868 OSG::PassiveWindowRefPtr pwin
=OSG::PassiveWindow::create();
871 // create the SimpleSceneManager helper
872 mgr
= OSG::SimpleSceneManager::create();
874 // create the window and initial camera/viewport
875 mgr
->setWindow(pwin
);
878 // for storing clipplane beacon we use a container
879 // collection attachment which we attach to the scene
880 // node. Otherwise the scene could not be saved correctly,
881 // as the beacons would be lost.
883 container
= OSG::ContainerCollection::create();
886 // Implementation details:
887 // For each clip plane we provide a ClipPlaneChunk, the plane geometry,
888 // the plane transform core and at least a plane color conveniently in
889 // a vector of type VecClipPlaneDetailsT. The next function call
890 // initializes this data structure.
892 createClipPlaneDetails();
897 scene
= OSG::Node::create();
898 scene
->setCore(OSG::Group::create());
899 scene
->addAttachment(container
);
902 // A place for accessing the box and torus.
904 vecGeometries
.push_back(NULL
);
905 vecGeometries
.push_back(NULL
);
908 // Build concrete clipping planes and update the clip plane details.
913 data1
._equation
= OSG::Vec4f(0,0,1,0);
914 data1
._enabled
= true;
916 data2
._equation
= OSG::Vec4f(1,0,0,0);
917 data2
._enabled
= false;
919 vecClipPlaneData
.push_back(data1
);
920 vecClipPlaneData
.push_back(data2
);
922 updateClipPlanes(vecClipPlaneData
);
927 // tell the manager what to manage
930 // show the whole scene
934 pwin
->dumpExtensions();
939 int main(int argc
, char *argv
[])
947 // Clean up the global held data