File: CompositePlacer

package info (click to toggle)
openscenegraph 3.2.3%2Bdfsg1-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 32,824 kB
  • sloc: cpp: 370,040; ansic: 9,071; java: 1,020; yacc: 548; objc: 288; makefile: 285; xml: 155; lex: 151
file content (104 lines) | stat: -rw-r--r-- 3,144 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library 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
 * OpenSceneGraph Public License for more details.
*/
// Written by Wang Rui, (C) 2010

#ifndef OSGPARTICLE_COMPOSITEPLACER
#define OSGPARTICLE_COMPOSITEPLACER

#include <osgParticle/Placer>
#include <osgParticle/Particle>

namespace osgParticle
{


/** A composite particle placer which allows particles to be generated from a union of placers. */
class CompositePlacer : public Placer
{
public:
    CompositePlacer() : Placer() {}

    CompositePlacer( const CompositePlacer& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY )
    : Placer(copy, copyop), _placers(copy._placers) {}

    META_Object( osgParticle, CompositePlacer );

    // Set a child placer at specific index
    void setPlacer( unsigned int i, Placer* p )
    {
        if (i<_placers.size()) _placers[i] = p;
        else addPlacer(p);
    }

    /// Add a child placer
    void addPlacer( Placer* p ) { _placers.push_back(p); }

    /// Remove a child placer
    void removePlacer( unsigned int i )
    { if (i<_placers.size()) _placers.erase(_placers.begin()+i); }

    /// Get a child placer
    Placer* getPlacer( unsigned int i ) { return _placers[i].get(); }
    const Placer* getPlacer( unsigned int i ) const { return _placers[i].get(); }

    /// Get number of placers
    unsigned int getNumPlacers() const { return _placers.size(); }

    /// Place a particle. Do not call it manually.
    inline void place( Particle* P ) const;

    /// return the volume of the box
    inline float volume() const;

    /// return the control position
    inline osg::Vec3 getControlPosition() const;

protected:
    virtual ~CompositePlacer() {}
    CompositePlacer& operator=( const CompositePlacer& ) { return *this; }

    typedef std::vector< osg::ref_ptr<Placer> > PlacerList;
    PlacerList _placers;
};

// INLINE METHODS

inline void CompositePlacer::place( Particle* P ) const
{
    rangef sizeRange( 0.0f, volume() );
    float current = 0.0f, selected = sizeRange.get_random();
    for ( PlacerList::const_iterator itr=_placers.begin(); itr!=_placers.end(); ++itr )
    {
        current += (*itr)->volume();
        if ( selected<=current ) (*itr)->place( P );
    }
}

inline float CompositePlacer::volume() const
{
    float total_size = 0.0f;
    for ( PlacerList::const_iterator itr=_placers.begin(); itr!=_placers.end(); ++itr )
        total_size += (*itr)->volume();
    return total_size;
}

inline osg::Vec3 CompositePlacer::getControlPosition() const
{
    if ( !_placers.size() ) return osg::Vec3();
    return _placers.front()->getControlPosition();
}


}

#endif