OpenSceneGraph/include/osgParticle/MultiSegmentPlacer
2012-03-21 17:36:20 +00:00

145 lines
4.0 KiB
C++

/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 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.
*/
//osgParticle - Copyright (C) 2002 Marco Jez
#ifndef OSGPARTICLE_MULTISEGMENT_PLACER
#define OSGPARTICLE_MULTISEGMENT_PLACER 1
#include <osgParticle/Export>
#include <osgParticle/Placer>
#include <osgParticle/Particle>
#include <vector>
#include <utility>
#include <osg/Notify>
#include <osg/CopyOp>
#include <osg/Object>
#include <osg/Vec3>
namespace osgParticle {
/** A polyline-shaped particle placer.
This placer class sets the position of incoming particles by choosing a random point on the
specified sequence of connected segments.
*/
class OSGPARTICLE_EXPORT MultiSegmentPlacer: public Placer {
public:
MultiSegmentPlacer();
MultiSegmentPlacer(const MultiSegmentPlacer& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
META_Object(osgParticle, MultiSegmentPlacer);
/// Get the number of vertices which define the segments.
inline int numVertices() const;
/// Get a vertex.
inline const osg::Vec3& getVertex(int i) const;
/// Set a vertex.
inline void setVertex(int i, const osg::Vec3& v);
/// Set a vertex.
inline void setVertex(int i, float x, float y, float z);
/// Add a vertex.
inline void addVertex(const osg::Vec3& v);
/// Add a vertex.
inline void addVertex(float x, float y, float z);
/// Remove a vertex.
inline void removeVertex(int i);
/// Place a partice. Called automatically by <CODE>ModularEmitter</CODE>, do not call this method manually.
void place(Particle* P) const;
/// return the length of the multi-segment
inline float volume() const;
/// return the control position
inline osg::Vec3 getControlPosition() const;
protected:
virtual ~MultiSegmentPlacer() {}
MultiSegmentPlacer& operator=(const MultiSegmentPlacer&) { return *this; }
private:
typedef std::pair<osg::Vec3, float> Vertex_data;
typedef std::vector<Vertex_data> Vertex_vector;
Vertex_vector _vx;
float _total_length;
void recompute_length();
};
// INLINE FUNCTIONS
inline int MultiSegmentPlacer::numVertices() const
{
return static_cast<int>(_vx.size());
}
inline const osg::Vec3& MultiSegmentPlacer::getVertex(int i) const
{
return _vx[i].first;
}
inline void MultiSegmentPlacer::setVertex(int i, const osg::Vec3& v)
{
_vx[i].first = v;
recompute_length();
}
inline void MultiSegmentPlacer::setVertex(int i, float x, float y, float z)
{
_vx[i].first.set(x, y, z);
recompute_length();
}
inline void MultiSegmentPlacer::addVertex(const osg::Vec3& v)
{
float l = 0;
if (_vx.size() > 0) {
l = (v - _vx.back().first).length();
}
_total_length += l;
_vx.push_back(std::make_pair(v, _total_length));
}
inline void MultiSegmentPlacer::addVertex(float x, float y, float z)
{
addVertex(osg::Vec3(x, y, z));
}
inline void MultiSegmentPlacer::removeVertex(int i)
{
_vx.erase(_vx.begin()+i);
recompute_length();
}
inline float MultiSegmentPlacer::volume() const
{
return _total_length;
}
inline osg::Vec3 MultiSegmentPlacer::getControlPosition() const
{
return _vx.empty() ? osg::Vec3(0.0f,0.0f,0.0f) : _vx[0].first;
}
}
#endif