diff --git a/include/osg/ClipNode b/include/osg/ClipNode index 367fc5ffb..4e7dde75f 100644 --- a/include/osg/ClipNode +++ b/include/osg/ClipNode @@ -34,10 +34,31 @@ class OSG_EXPORT ClipNode : public Group META_Node(osg, ClipNode); + enum ReferenceFrame + { + RELATIVE_RF, + ABSOLUTE_RF + }; + + /** Set the light sources's ReferenceFrame, either to be relative to its + * parent reference frame, or relative to an absolute coordinate + * frame. RELATIVE_RF is the default. + * Note: setting the ReferenceFrame to be ABSOLUTE_RF will + * also set the CullingActive flag on the light source, and hence all + * of its parents, to false, thereby disabling culling of it and + * all its parents. This is necessary to prevent inappropriate + * culling, but may impact cull times if the absolute light source is + * deep in the scene graph. It is therefore recommended to only use + * absolute light source at the top of the scene. + */ + void setReferenceFrame(ReferenceFrame rf); + + ReferenceFrame getReferenceFrame() const { return _referenceFrame; } + + /** Creates six clip planes corresponding to the given BoundingBox. */ void createClipBox(const BoundingBox& bb,unsigned int clipPlaneNumberBase=0); - /** Adds the clipplane. Returns true on success, and false if the plane * has already been added, or if clipplane is NULL. */ bool addClipPlane(ClipPlane* clipplane); @@ -81,8 +102,10 @@ class OSG_EXPORT ClipNode : public Group virtual ~ClipNode(); - StateAttribute::GLModeValue _value; - ClipPlaneList _planes; + StateAttribute::GLModeValue _value; + ClipPlaneList _planes; + + ReferenceFrame _referenceFrame; }; } diff --git a/src/osg/ClipNode.cpp b/src/osg/ClipNode.cpp index 6b3b27d56..8d5acfb54 100644 --- a/src/osg/ClipNode.cpp +++ b/src/osg/ClipNode.cpp @@ -17,7 +17,8 @@ using namespace osg; ClipNode::ClipNode(): - _value(StateAttribute::ON) + _value(StateAttribute::ON), + _referenceFrame(RELATIVE_RF) { setStateSet(new StateSet); } @@ -43,6 +44,12 @@ ClipNode::~ClipNode() { } + +void ClipNode::setReferenceFrame(ReferenceFrame rf) +{ + _referenceFrame = rf; +} + // Create a 6 clip planes to create a clip box. void ClipNode::createClipBox(const BoundingBox& bb,unsigned int clipPlaneNumberBase) { diff --git a/src/osgPlugins/ive/ClipNode.cpp b/src/osgPlugins/ive/ClipNode.cpp index eb99dd215..b9afe6682 100644 --- a/src/osgPlugins/ive/ClipNode.cpp +++ b/src/osgPlugins/ive/ClipNode.cpp @@ -32,6 +32,11 @@ void ClipNode::write(DataOutputStream* out){ throw Exception("ClipNode::write(): Could not cast this osg::ClipNode to an osg::Group."); // Write ClipNode's properties. + if ( out->getVersion() >= VERSION_0037 ) + { + out->writeInt((int)getReferenceFrame()); + } + out->writeUInt(getNumClipPlanes()); for (unsigned int i=0;igetVersion() >= VERSION_0037 ) + { + setReferenceFrame((osg::ClipNode::ReferenceFrame) in->readInt()); + } + unsigned int numClipPlanes = in->readUInt(); for (unsigned int i=0;i(obj); + if (fr[0].matchWord("referenceFrame")) + { + if (fr[1].matchWord("ABSOLUTE")) + { + clipnode.setReferenceFrame(ClipNode::ABSOLUTE_RF); + fr += 2; + iteratorAdvanced = true; + } + if (fr[1].matchWord("RELATIVE")) + { + clipnode.setReferenceFrame(ClipNode::RELATIVE_RF); + fr += 2; + iteratorAdvanced = true; + } + } + osg::ref_ptr sa=0; while((sa=fr.readStateAttribute())!=0) { @@ -43,6 +59,17 @@ bool ClipNode_writeLocalData(const Object& obj, Output& fw) { const ClipNode& clipnode = static_cast(obj); + fw.indent() << "referenceFrame "; + switch (clipnode.getReferenceFrame()) + { + case ClipNode::ABSOLUTE_RF: + fw << "ABSOLUTE\n"; + break; + case ClipNode::RELATIVE_RF: + default: + fw << "RELATIVE\n"; + }; + for(unsigned int i=0;iget()); + if (node.getReferenceFrame()==osg::ClipNode::RELATIVE_RF) + { + addPositionedAttribute(&matrix,itr->get()); + } + else + { + addPositionedAttribute(0,itr->get()); + } } handle_cull_callbacks_and_traverse(node); diff --git a/src/osgWrappers/osg/ClipNode.cpp b/src/osgWrappers/osg/ClipNode.cpp index bd6f571a8..8162ae153 100644 --- a/src/osgWrappers/osg/ClipNode.cpp +++ b/src/osgWrappers/osg/ClipNode.cpp @@ -30,6 +30,12 @@ TYPE_NAME_ALIAS(std::vector< osg::ref_ptr< osg::ClipPlane > >, osg::ClipNode::ClipPlaneList) +BEGIN_ENUM_REFLECTOR(osg::ClipNode::ReferenceFrame) + I_DeclaringFile("osg/ClipNode"); + I_EnumLabel(osg::ClipNode::RELATIVE_RF); + I_EnumLabel(osg::ClipNode::ABSOLUTE_RF); +END_REFLECTOR + BEGIN_OBJECT_REFLECTOR(osg::ClipNode) I_DeclaringFile("osg/ClipNode"); I_BaseType(osg::Group); @@ -70,6 +76,16 @@ BEGIN_OBJECT_REFLECTOR(osg::ClipNode) __void__accept__osg_NodeVisitor_R1, "Visitor Pattern : calls the apply method of a NodeVisitor with this node's type. ", ""); + I_Method1(void, setReferenceFrame, IN, osg::ClipNode::ReferenceFrame, rf, + Properties::NON_VIRTUAL, + __void__setReferenceFrame__ReferenceFrame, + "Set the light sources's ReferenceFrame, either to be relative to its parent reference frame, or relative to an absolute coordinate frame. ", + "RELATIVE_RF is the default. Note: setting the ReferenceFrame to be ABSOLUTE_RF will also set the CullingActive flag on the light source, and hence all of its parents, to false, thereby disabling culling of it and all its parents. This is necessary to prevent inappropriate culling, but may impact cull times if the absolute light source is deep in the scene graph. It is therefore recommended to only use absolute light source at the top of the scene. "); + I_Method0(osg::ClipNode::ReferenceFrame, getReferenceFrame, + Properties::NON_VIRTUAL, + __ReferenceFrame__getReferenceFrame, + "", + ""); I_MethodWithDefaults2(void, createClipBox, IN, const osg::BoundingBox &, bb, , IN, unsigned int, clipPlaneNumberBase, 0, Properties::NON_VIRTUAL, __void__createClipBox__C5_BoundingBox_R1__unsigned_int, @@ -148,6 +164,9 @@ BEGIN_OBJECT_REFLECTOR(osg::ClipNode) I_SimpleProperty(osg::StateAttribute::GLModeValue, LocalStateSetModes, 0, __void__setLocalStateSetModes__StateAttribute_GLModeValue); + I_SimpleProperty(osg::ClipNode::ReferenceFrame, ReferenceFrame, + __ReferenceFrame__getReferenceFrame, + __void__setReferenceFrame__ReferenceFrame); END_REFLECTOR BEGIN_VALUE_REFLECTOR(osg::ref_ptr< osg::ClipPlane >)