From: frohlich Date: Wed, 26 Dec 2007 19:05:06 +0000 (+0000) Subject: Modified Files: X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=37c4dcf8ba1b790dd63a93b62ed0c41d8f1fe18b;p=simgear.git Modified Files: Makefile.am Added Files: SGClipGroup.cxx SGClipGroup.hxx: Add helper group node for reuse of clipping planes. Will be used for the panel code. --- diff --git a/simgear/scene/model/Makefile.am b/simgear/scene/model/Makefile.am index 192af7d3..49c69754 100644 --- a/simgear/scene/model/Makefile.am +++ b/simgear/scene/model/Makefile.am @@ -13,6 +13,7 @@ include_HEADERS = \ persparam.hxx \ placement.hxx \ placementtrans.hxx \ + SGClipGroup.hxx \ SGMaterialAnimation.hxx \ SGOffsetTransform.hxx \ SGRotateTransform.hxx \ @@ -29,6 +30,7 @@ libsgmodel_a_SOURCES = \ placement.cxx \ placementtrans.cxx \ shadanim.cxx \ + SGClipGroup.cxx \ SGMaterialAnimation.cxx \ SGOffsetTransform.cxx \ SGRotateTransform.cxx \ diff --git a/simgear/scene/model/SGClipGroup.cxx b/simgear/scene/model/SGClipGroup.cxx new file mode 100644 index 00000000..fdf9305a --- /dev/null +++ b/simgear/scene/model/SGClipGroup.cxx @@ -0,0 +1,159 @@ +/* -*-c++-*- + * + * Copyright (C) 2006-2007 Mathias Froehlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +#include "SGClipGroup.hxx" + +#include +#include +#include +#include + +#include +#include +#include + +class SGClipGroup::ClipRenderBin : public osgUtil::RenderBin { +public: + virtual osg::Object* cloneType() const + { return new ClipRenderBin(); } + virtual osg::Object* clone(const osg::CopyOp& copyop) const + { return new ClipRenderBin; } + virtual bool isSameKindAs(const osg::Object* obj) const + { return dynamic_cast(obj)!=0L; } + virtual const char* libraryName() const + { return "SimGear"; } + virtual const char* className() const + { return "ClipRenderBin"; } + + virtual void drawImplementation(osg::RenderInfo& renderInfo, + osgUtil::RenderLeaf*& previous) + { + osg::State* state = renderInfo.getState(); + + glPushAttrib(GL_TRANSFORM_BIT); + + state->applyModelViewMatrix(mModelView.get()); + for (unsigned i = 0; i < mClipPlanes.size(); ++i) + mClipPlanes[i]->apply(*state); + + osgUtil::RenderBin::drawImplementation(renderInfo, previous); + + glPopAttrib(); + } + + virtual void reset() + { mClipPlanes.resize(0); } + + std::vector > mClipPlanes; + osg::ref_ptr mModelView; +}; + +osgUtil::RegisterRenderBinProxy +SGClipGroup::clipBinProxy("ClipRenderBin", new SGClipGroup::ClipRenderBin); + +class SGClipGroup::CullCallback : public osg::NodeCallback { +public: + virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + { + osgUtil::CullVisitor* cullVisitor; + cullVisitor = dynamic_cast(nv); + + if (cullVisitor) { + osgUtil::RenderBin* renderBin = cullVisitor->getCurrentRenderBin(); + ClipRenderBin* clipBin = dynamic_cast(renderBin); + SGClipGroup* clipGroup; + clipGroup = dynamic_cast(node); + if (clipGroup && clipBin) { + clipBin->mClipPlanes = clipGroup->mClipPlanes; + clipBin->mModelView = cullVisitor->getModelViewMatrix(); + } + } + + // note, callback is responsible for scenegraph traversal so + // they must call traverse(node,nv) to ensure that the + // scene graph subtree (and associated callbacks) are traversed. + traverse(node, nv); + } +}; + +static osg::Vec4d clipPlane(const osg::Vec2& p0, const osg::Vec2& p1) +{ + osg::Vec2d v(p1[0] - p0[0], p1[1] - p0[1]); + return osg::Vec4d(v[1], -v[0], 0, v[0]*p0[1] - v[1]*p0[0]); +} + +SGClipGroup::SGClipGroup() +{ + getOrCreateStateSet()->setRenderBinDetails(0, "ClipRenderBin"); + setCullCallback(new CullCallback); +} + +osg::BoundingSphere +SGClipGroup::computeBound() const +{ + return _initialBound; +} + +void +SGClipGroup::addClipPlane(unsigned num, const SGVec2d& p0, + const SGVec2d& p1) +{ + osg::Vec2d v(p1[0] - p0[0], p1[1] - p0[1]); + osg::Vec4d planeEquation(v[1], -v[0], 0, v[0]*p0[1] - v[1]*p0[0]); + osg::ClipPlane* clipPlane = new osg::ClipPlane(num, planeEquation); + getStateSet()->setAssociatedModes(clipPlane, osg::StateAttribute::ON); + mClipPlanes.push_back(clipPlane); +} + +void +SGClipGroup::setDrawArea(const SGVec2d& lowerLeft, + const SGVec2d& upperRight) +{ + setDrawArea(lowerLeft, + SGVec2d(lowerLeft[0], upperRight[1]), + SGVec2d(upperRight[0], lowerLeft[1]), + upperRight); +} + +void +SGClipGroup::setDrawArea(const SGVec2d& bottomLeft, + const SGVec2d& topLeft, + const SGVec2d& bottomRight, + const SGVec2d& topRight) +{ +#if (OPENSCENEGRAPH_MAJOR_VERSION > 2) || (OPENSCENEGRAPH_MINOR_VERSION > 2) + for (unsigned i = 0; i < mClipPlanes.size(); ++i) + getStateSet()->removeAssociatedModes(mClipPlanes[i].get()); +#endif + mClipPlanes.resize(0); + addClipPlane(2, bottomLeft, topLeft); + addClipPlane(3, topLeft, topRight); + addClipPlane(4, topRight, bottomRight); + addClipPlane(5, bottomRight, bottomLeft); + _initialBound.init(); + _initialBound.expandBy(osg::Vec3(bottomLeft[0], bottomLeft[1], 0)); + _initialBound.expandBy(osg::Vec3(topLeft[0], topLeft[1], 0)); + _initialBound.expandBy(osg::Vec3(bottomRight[0], bottomRight[1], 0)); + _initialBound.expandBy(osg::Vec3(topRight[0], topRight[1], 0)); + _boundingSphere = _initialBound; + _boundingSphereComputed = true; +} + diff --git a/simgear/scene/model/SGClipGroup.hxx b/simgear/scene/model/SGClipGroup.hxx new file mode 100644 index 00000000..7961bfb9 --- /dev/null +++ b/simgear/scene/model/SGClipGroup.hxx @@ -0,0 +1,55 @@ +/* -*-c++-*- + * + * Copyright (C) 2006-2007 Mathias Froehlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +#ifndef SG_CLIP_GROUP_HXX +#define SG_CLIP_GROUP_HXX + +#include +#include +#include +#include +#include + +#include + +class SGClipGroup : public osg::Group { +public: + SGClipGroup(); + + virtual osg::BoundingSphere computeBound() const; + + void addClipPlane(unsigned num, const SGVec2d& p0, const SGVec2d& p1); + void setDrawArea(const SGVec2d& lowerLeft, const SGVec2d& upperRight); + void setDrawArea(const SGVec2d& bottomLeft, + const SGVec2d& topLeft, + const SGVec2d& bottomRight, + const SGVec2d& topRight); + +protected: + class CullCallback; + class ClipRenderBin; + + std::vector > mClipPlanes; + + static osgUtil::RegisterRenderBinProxy clipBinProxy; +}; + +#endif