root/OpenSceneGraph/trunk/include/osgParticle/DomainOperator @ 13041

Revision 13041, 7.7 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
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
22namespace osgParticle
23{
24
25
26/** A domain operator which accepts different domain shapes as the parameter.
27    It can be derived to implement operators that require particles interacting with domains.
28    Refer to David McAllister's Particle System API (http://www.particlesystems.org)
29*/
30class OSGPARTICLE_EXPORT DomainOperator : public Operator
31{
32public:
33    struct Domain
34    {
35        enum Type
36        {
37            UNDEFINED_DOMAIN = 0,
38            POINT_DOMAIN,
39            LINE_DOMAIN,
40            TRI_DOMAIN,
41            RECT_DOMAIN,
42            PLANE_DOMAIN,
43            SPHERE_DOMAIN,
44            BOX_DOMAIN,
45            DISK_DOMAIN
46        };
47
48        Domain( Type t ) : r1(0.0f), r2(0.0f), type(t) {}
49        osg::Plane plane;
50        osg::Vec3 v1;
51        osg::Vec3 v2;
52        osg::Vec3 v3;
53        osg::Vec3 s1;
54        osg::Vec3 s2;
55        float r1;
56        float r2;
57        Type type;
58    };
59
60    DomainOperator()
61    : Operator()
62    {}
63
64    DomainOperator( const DomainOperator& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY )
65    : Operator(copy, copyop), _domains(copy._domains), _backupDomains(copy._backupDomains)
66    {}
67
68    META_Object( osgParticle, DomainOperator );
69
70    /// Add a point domain
71    inline void addPointDomain( const osg::Vec3& p );
72
73    /// Add a line segment domain
74    inline void addLineSegmentDomain( const osg::Vec3& v1, const osg::Vec3& v2 );
75
76    /// Add a triangle domain
77    inline void addTriangleDomain( const osg::Vec3& v1, const osg::Vec3& v2, const osg::Vec3& v3 );
78
79    /// Add a rectangle domain
80    inline void addRectangleDomain( const osg::Vec3& corner, const osg::Vec3& w, const osg::Vec3& h );
81
82    /// Add a plane domain
83    inline void addPlaneDomain( const osg::Plane& plane );
84
85    /// Add a sphere domain
86    inline void addSphereDomain( const osg::Vec3& c, float r );
87
88    /// Add a box domain
89    inline void addBoxDomain( const osg::Vec3& min, const osg::Vec3& max );
90
91    /// Add a disk domain
92    inline void addDiskDomain( const osg::Vec3& c, const osg::Vec3& n, float r1, float r2=0.0f );
93
94    /// Add a domain object directly, used by the .osg wrappers and serializers.
95    void addDomain( const Domain& domain ) { _domains.push_back(domain); }
96
97    /// Get a domain object directly, used by the .osg wrappers and serializers.
98    const Domain& getDomain( unsigned int i ) const { return _domains[i]; }
99
100    /// Remove a domain at specific index
101    void removeDomain( unsigned int i )
102    { if (i<_domains.size()) _domains.erase(_domains.begin() + i); }
103
104    /// Remove all existing domains
105    void removeAllDomains() { _domains.clear(); }
106
107    /// Get number of domains
108    unsigned int getNumDomains() const { return _domains.size(); }
109
110    /// Apply the acceleration to a particle. Do not call this method manually.
111    void operate( Particle* P, double dt );
112
113    /// Perform some initializations. Do not call this method manually.
114    void beginOperate( Program* prg );
115
116    /// Perform some post-operations. Do not call this method manually.
117    void endOperate();
118
119protected:
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
141inline void DomainOperator::addPointDomain( const osg::Vec3& p )
142{
143    Domain domain( Domain::POINT_DOMAIN );
144    domain.v1 = p;
145    _domains.push_back( domain );
146}
147
148inline 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
157inline 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
168inline 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
179inline 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
186inline 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
194inline 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
202inline 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
213inline 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
227inline 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
Note: See TracBrowser for help on using the browser.