OSG  3.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DomainOperator.h
Go to the documentation of this file.
1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 Robert Osfield
2  *
3  * This library is open source and may be redistributed and/or modified under
4  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5  * (at your option) any later version. The full license is in LICENSE file
6  * included with this distribution, and on the openscenegraph.org website.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * OpenSceneGraph Public License for more details.
12 */
13 // Written by Wang Rui, (C) 2010
14 
15 #ifndef OSGPARTICLE_DOMAINOPERATOR
16 #define OSGPARTICLE_DOMAINOPERATOR
17 
18 #include <osg/Plane>
19 #include <osgParticle/Operator>
20 #include <osgParticle/Particle>
21 
22 namespace osgParticle
23 {
24 
25 
31 {
32 public:
33  struct Domain
34  {
35  enum Type
36  {
37  UNDEFINED_DOMAIN = 0,
45  DISK_DOMAIN
46  };
47 
48  Domain( Type t ) : r1(0.0f), r2(0.0f), type(t) {}
55  float r1;
56  float r2;
58  };
59 
61  : Operator()
62  {}
63 
65  : Operator(copy, copyop), _domains(copy._domains), _backupDomains(copy._backupDomains)
66  {}
67 
69 
71  inline void addPointDomain( const osg::Vec3& p );
72 
74  inline void addLineSegmentDomain( const osg::Vec3& v1, const osg::Vec3& v2 );
75 
77  inline void addTriangleDomain( const osg::Vec3& v1, const osg::Vec3& v2, const osg::Vec3& v3 );
78 
80  inline void addRectangleDomain( const osg::Vec3& corner, const osg::Vec3& w, const osg::Vec3& h );
81 
83  inline void addPlaneDomain( const osg::Plane& plane );
84 
86  inline void addSphereDomain( const osg::Vec3& c, float r );
87 
89  inline void addBoxDomain( const osg::Vec3& min, const osg::Vec3& max );
90 
92  inline void addDiskDomain( const osg::Vec3& c, const osg::Vec3& n, float r1, float r2=0.0f );
93 
95  void addDomain( const Domain& domain ) { _domains.push_back(domain); }
96 
98  const Domain& getDomain( unsigned int i ) const { return _domains[i]; }
99 
101  void removeDomain( unsigned int i )
102  { if (i<_domains.size()) _domains.erase(_domains.begin() + i); }
103 
105  void removeAllDomains() { _domains.clear(); }
106 
108  unsigned int getNumDomains() const { return _domains.size(); }
109 
111  void operate( Particle* P, double dt );
112 
114  void beginOperate( Program* prg );
115 
117  void endOperate();
118 
119 protected:
120  virtual ~DomainOperator() {}
121  DomainOperator& operator=( const DomainOperator& ) { return *this; }
122 
123  virtual void handlePoint( const Domain& /*domain*/, Particle* /*P*/, double /*dt*/ ) { ignore("Point"); }
124  virtual void handleLineSegment( const Domain& /*domain*/, Particle* /*P*/, double /*dt*/ ) { ignore("LineSegment"); }
125  virtual void handleTriangle( const Domain& /*domain*/, Particle* /*P*/, double /*dt*/ ) { ignore("Triangle"); }
126  virtual void handleRectangle( const Domain& /*domain*/, Particle* /*P*/, double /*dt*/ ) { ignore("Rectangle"); }
127  virtual void handlePlane( const Domain& /*domain*/, Particle* /*P*/, double /*dt*/ ) { ignore("Plane"); }
128  virtual void handleSphere( const Domain& /*domain*/, Particle* /*P*/, double /*dt*/ ) { ignore("Sphere"); }
129  virtual void handleBox( const Domain& /*domain*/, Particle* /*P*/, double /*dt*/ ) { ignore("Box"); }
130  virtual void handleDisk( const Domain& /*domain*/, Particle* /*P*/, double /*dt*/ ) { ignore("Disk"); }
131 
132  inline void computeNewBasis( const osg::Vec3&, const osg::Vec3&, osg::Vec3&, osg::Vec3& );
133  inline void ignore( const std::string& func );
134 
135  std::vector<Domain> _domains;
136  std::vector<Domain> _backupDomains;
137 };
138 
139 // INLINE METHODS
140 
142 {
143  Domain domain( Domain::POINT_DOMAIN );
144  domain.v1 = p;
145  _domains.push_back( domain );
146 }
147 
148 inline void DomainOperator::addLineSegmentDomain( const osg::Vec3& v1, const osg::Vec3& v2 )
149 {
150  Domain domain( Domain::LINE_DOMAIN );
151  domain.v1 = v1;
152  domain.v2 = v2;
153  domain.r1 = (v2 - v1).length();
154  _domains.push_back( domain );
155 }
156 
157 inline void DomainOperator::addTriangleDomain( const osg::Vec3& v1, const osg::Vec3& v2, const osg::Vec3& v3 )
158 {
159  Domain domain( Domain::TRI_DOMAIN );
160  domain.v1 = v1;
161  domain.v2 = v2;
162  domain.v3 = v3;
163  domain.plane.set(v1, v2, v3);
164  computeNewBasis( v2-v1, v3-v1, domain.s1, domain.s2 );
165  _domains.push_back( domain );
166 }
167 
168 inline void DomainOperator::addRectangleDomain( const osg::Vec3& corner, const osg::Vec3& w, const osg::Vec3& h )
169 {
170  Domain domain( Domain::RECT_DOMAIN );
171  domain.v1 = corner;
172  domain.v2 = w;
173  domain.v3 = h;
174  domain.plane.set(corner, corner+w, corner+h);
175  computeNewBasis( w, h, domain.s1, domain.s2 );
176  _domains.push_back( domain );
177 }
178 
179 inline void DomainOperator::addPlaneDomain( const osg::Plane& plane )
180 {
181  Domain domain( Domain::PLANE_DOMAIN );
182  domain.plane.set(plane);
183  _domains.push_back( domain );
184 }
185 
186 inline void DomainOperator::addSphereDomain( const osg::Vec3& c, float r )
187 {
188  Domain domain( Domain::SPHERE_DOMAIN );
189  domain.v1 = c;
190  domain.r1 = r;
191  _domains.push_back( domain );
192 }
193 
194 inline void DomainOperator::addBoxDomain( const osg::Vec3& min, const osg::Vec3& max )
195 {
196  Domain domain( Domain::BOX_DOMAIN );
197  domain.v1 = min;
198  domain.v2 = max;
199  _domains.push_back( domain );
200 }
201 
202 inline void DomainOperator::addDiskDomain( const osg::Vec3& c, const osg::Vec3& n, float r1, float r2 )
203 {
204  Domain domain( Domain::DISK_DOMAIN );
205  domain.v1 = c;
206  domain.v2 = n;
207  domain.r1 = r1;
208  domain.r2 = r2;
209  domain.plane.set(n, c);
210  _domains.push_back( domain );
211 }
212 
213 inline void DomainOperator::computeNewBasis( const osg::Vec3& u, const osg::Vec3& v, osg::Vec3& s1, osg::Vec3& s2 )
214 {
215  // Copied from David McAllister's Particle System API (http://www.particlesystems.org), pDomain.h
216  osg::Vec3 w = u ^ v;
217  float det = w.z()*u.x()*v.y() - w.z()*u.y()*v.x() - u.z()*w.x()*v.y() -
218  u.x()*v.z()*w.y() + v.z()*w.x()*u.y() + u.z()*v.x()*w.y();
219  det = 1.0f / det;
220 
221  s1.set( v.y()*w.z() - v.z()*w.y(), v.z()*w.x() - v.x()*w.z(), v.x()*w.y() - v.y()*w.x() );
222  s1 = s1 * det;
223  s2.set( u.y()*w.z() - u.z()*w.y(), u.z()*w.x() - u.x()*w.z(), u.x()*w.y() - u.y()*w.x() );
224  s2 = s2 * (-det);
225 }
226 
227 inline void DomainOperator::ignore( const std::string& func )
228 {
229  OSG_NOTICE << className() << ": " << func << " domain not yet implemented. " << std::endl;
230 }
231 
232 
233 }
234 
235 #endif
std::vector< Domain > _domains
#define OSG_NOTICE
Definition: Notify.h:86
void removeDomain(unsigned int i)
Remove a domain at specific index.
void addPointDomain(const osg::Vec3 &p)
Add a point domain.
const Domain & getDomain(unsigned int i) const
Get a domain object directly, used by the .osg wrappers and serializers.
virtual void handleSphere(const Domain &, Particle *, double)
void addPlaneDomain(const osg::Plane &plane)
Add a plane domain.
value_type & x()
Definition: Vec3f.h:80
unsigned int getNumDomains() const
Get number of domains.
value_type & z()
Definition: Vec3f.h:82
void ignore(const std::string &func)
virtual void handleBox(const Domain &, Particle *, double)
void set(const Plane &pl)
Definition: Plane.h:105
void removeAllDomains()
Remove all existing domains.
void addRectangleDomain(const osg::Vec3 &corner, const osg::Vec3 &w, const osg::Vec3 &h)
Add a rectangle domain.
virtual void handlePlane(const Domain &, Particle *, double)
DomainOperator & operator=(const DomainOperator &)
virtual const char * className() const
Definition: Operator.h:41
virtual void handleRectangle(const Domain &, Particle *, double)
void addSphereDomain(const osg::Vec3 &c, float r)
Add a sphere domain.
#define OSGPARTICLE_EXPORT
Definition: Export.h:40
void addDomain(const Domain &domain)
Add a domain object directly, used by the .osg wrappers and serializers.
void addBoxDomain(const osg::Vec3 &min, const osg::Vec3 &max)
Add a box domain.
#define META_Object(library, name)
Definition: Object.h:42
void set(value_type x, value_type y, value_type z)
Definition: Vec3f.h:67
void addLineSegmentDomain(const osg::Vec3 &v1, const osg::Vec3 &v2)
Add a line segment domain.
value_type & y()
Definition: Vec3f.h:81
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
Definition: GLU.h:71
virtual void handleTriangle(const Domain &, Particle *, double)
A plane class. It can be used to represent an infinite plane.
Definition: Plane.h:33
DomainOperator(const DomainOperator &copy, const osg::CopyOp &copyop=osg::CopyOp::SHALLOW_COPY)
void addDiskDomain(const osg::Vec3 &c, const osg::Vec3 &n, float r1, float r2=0.0f)
Add a disk domain.
virtual void handleLineSegment(const Domain &, Particle *, double)
void addTriangleDomain(const osg::Vec3 &v1, const osg::Vec3 &v2, const osg::Vec3 &v3)
Add a triangle domain.
void computeNewBasis(const osg::Vec3 &, const osg::Vec3 &, osg::Vec3 &, osg::Vec3 &)
virtual void handlePoint(const Domain &, Particle *, double)
std::vector< Domain > _backupDomains
virtual void handleDisk(const Domain &, Particle *, double)