]> git.mxchange.org Git - simgear.git/blob - simgear/scene/model/SGClipGroup.cxx
Make return type from loadPagedModel explicit.
[simgear.git] / simgear / scene / model / SGClipGroup.cxx
1 /* -*-c++-*-
2  *
3  * Copyright (C) 2006-2007 Mathias Froehlich 
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18  * MA 02110-1301, USA.
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #  include <simgear_config.h>
24 #endif
25
26 #include "SGClipGroup.hxx"
27
28 #include <osg/ClipPlane>
29 #include <osg/NodeCallback>
30 #include <osg/StateSet>
31 #include <osg/Version>
32
33 #include <osgUtil/RenderBin>
34 #include <osgUtil/RenderLeaf>
35 #include <osgUtil/CullVisitor>
36
37 class SGClipGroup::ClipRenderBin : public osgUtil::RenderBin {
38 public:
39   virtual osg::Object* cloneType() const
40   { return new ClipRenderBin(); }
41   virtual osg::Object* clone(const osg::CopyOp& copyop) const
42   { return new ClipRenderBin; }
43   virtual bool isSameKindAs(const osg::Object* obj) const
44   { return dynamic_cast<const ClipRenderBin*>(obj)!=0L; }
45   virtual const char* libraryName() const
46   { return "SimGear"; }
47   virtual const char* className() const
48   { return "ClipRenderBin"; }
49
50   virtual void drawImplementation(osg::RenderInfo& renderInfo,
51                                   osgUtil::RenderLeaf*& previous)
52   {
53     osg::State* state = renderInfo.getState();
54
55     state->applyModelViewMatrix(mModelView.get());
56     for (unsigned i = 0; i < mClipPlanes.size(); ++i) {
57       osg::StateAttribute::GLMode planeNum;
58       planeNum = GL_CLIP_PLANE0 + mClipPlanes[i]->getClipPlaneNum();
59       state->applyMode(planeNum, false);
60       glClipPlane(planeNum, mClipPlanes[i]->getClipPlane().ptr());
61     }
62
63     osgUtil::RenderBin::drawImplementation(renderInfo, previous);
64   }
65
66   virtual void reset()
67   { mClipPlanes.resize(0); }
68  
69   std::vector<osg::ref_ptr<osg::ClipPlane> > mClipPlanes;
70   osg::ref_ptr<osg::RefMatrix> mModelView;
71 };
72
73 struct SGClipGroup::ClipBinRegistrar
74 {
75     ClipBinRegistrar()
76     {
77         osgUtil::RenderBin
78             ::addRenderBinPrototype("ClipRenderBin",
79                                     new SGClipGroup::ClipRenderBin);
80     }
81     static ClipBinRegistrar registrar;
82 };
83
84 SGClipGroup::ClipBinRegistrar SGClipGroup::ClipBinRegistrar::registrar;
85
86 class SGClipGroup::CullCallback : public osg::NodeCallback {
87 public:
88   virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
89   {
90     osgUtil::CullVisitor* cullVisitor;
91     cullVisitor = dynamic_cast<osgUtil::CullVisitor*>(nv);
92     
93     if (cullVisitor) {
94       osgUtil::RenderBin* renderBin = cullVisitor->getCurrentRenderBin();
95       ClipRenderBin* clipBin = dynamic_cast<ClipRenderBin*>(renderBin);
96       SGClipGroup* clipGroup;
97       clipGroup = dynamic_cast<SGClipGroup*>(node);
98       if (clipGroup && clipBin) {
99         clipBin->mClipPlanes = clipGroup->mClipPlanes;
100         clipBin->mModelView = cullVisitor->getModelViewMatrix();
101       }
102     }
103     
104     // note, callback is responsible for scenegraph traversal so
105     // they must call traverse(node,nv) to ensure that the
106     // scene graph subtree (and associated callbacks) are traversed.
107     traverse(node, nv);
108   }
109 };
110
111 #if 0
112 static osg::Vec4d clipPlane(const osg::Vec2& p0, const osg::Vec2& p1)
113 {
114   osg::Vec2d v(p1[0] - p0[0], p1[1] - p0[1]);
115   return osg::Vec4d(v[1], -v[0], 0, v[0]*p0[1] - v[1]*p0[0]);
116 }
117 #endif
118
119 SGClipGroup::SGClipGroup()
120 {
121   getOrCreateStateSet()->setRenderBinDetails(0, "ClipRenderBin");
122   setCullCallback(new CullCallback);
123 }
124
125 SGClipGroup::SGClipGroup(const SGClipGroup& clip, const osg::CopyOp& copyop) :
126   osg::Group(clip, copyop)
127 {
128   for (unsigned i = 0; i < mClipPlanes.size(); ++i) {
129     osg::StateAttribute* sa = copyop(mClipPlanes[i].get());
130     mClipPlanes.push_back(static_cast<osg::ClipPlane*>(sa));
131   }
132 }
133
134 osg::BoundingSphere
135 SGClipGroup::computeBound() const
136 {
137   return _initialBound;
138 }
139
140 void
141 SGClipGroup::addClipPlane(unsigned num, const SGVec2d& p0,
142                           const SGVec2d& p1)
143 {
144   osg::Vec2d v(p1[0] - p0[0], p1[1] - p0[1]);
145   osg::Vec4d planeEquation(v[1], -v[0], 0, v[0]*p0[1] - v[1]*p0[0]);
146   osg::ClipPlane* clipPlane = new osg::ClipPlane(num, planeEquation);
147   getStateSet()->setAssociatedModes(clipPlane, osg::StateAttribute::ON);
148   mClipPlanes.push_back(clipPlane);
149 }
150
151 void
152 SGClipGroup::setDrawArea(const SGVec2d& lowerLeft,
153                          const SGVec2d& upperRight)
154 {
155   setDrawArea(lowerLeft,
156               SGVec2d(lowerLeft[0], upperRight[1]),
157               SGVec2d(upperRight[0], lowerLeft[1]),
158               upperRight);
159 }
160
161 void
162 SGClipGroup::setDrawArea(const SGVec2d& bottomLeft,
163                          const SGVec2d& topLeft,
164                          const SGVec2d& bottomRight,
165                          const SGVec2d& topRight)
166 {
167 #if (OPENSCENEGRAPH_MAJOR_VERSION > 2) || (OPENSCENEGRAPH_MINOR_VERSION > 2)
168   for (unsigned i = 0; i < mClipPlanes.size(); ++i)
169     getStateSet()->removeAssociatedModes(mClipPlanes[i].get());
170 #endif
171   mClipPlanes.resize(0);
172   addClipPlane(2, bottomLeft, topLeft);
173   addClipPlane(3, topLeft, topRight);
174   addClipPlane(4, topRight, bottomRight);
175   addClipPlane(5, bottomRight, bottomLeft);
176   _initialBound.init();
177   _initialBound.expandBy(osg::Vec3(bottomLeft[0], bottomLeft[1], 0));
178   _initialBound.expandBy(osg::Vec3(topLeft[0], topLeft[1], 0));
179   _initialBound.expandBy(osg::Vec3(bottomRight[0], bottomRight[1], 0));
180   _initialBound.expandBy(osg::Vec3(topRight[0], topRight[1], 0));
181   _boundingSphere = _initialBound;
182   _boundingSphereComputed = true;
183 }
184