/* -*-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_ANGULARDAMPINGOPERATOR #define OSGPARTICLE_ANGULARDAMPINGOPERATOR #include #include namespace osgParticle { /** A angular damping operator applies damping constant to particle's angular velocity. Refer to David McAllister's Particle System API (http://www.particlesystems.org) */ class AngularDampingOperator : public Operator { public: AngularDampingOperator() : Operator(), _cutoffLow(0.0f), _cutoffHigh(FLT_MAX) {} AngularDampingOperator( const AngularDampingOperator& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY ) : Operator(copy, copyop), _damping(copy._damping), _cutoffLow(copy._cutoffLow), _cutoffHigh(copy._cutoffHigh) {} META_Object( osgParticle, AngularDampingOperator ); /// Set the damping factors void setDamping( float x, float y, float z ) { _damping.set(x, y, z); } void setDamping( const osg::Vec3& damping ) { _damping = damping; } /// Set the damping factors to one value void setDamping( float x ) { _damping.set(x, x, x); } /// Get the damping factors void getDamping( float& x, float& y, float& z ) const { x = _damping.x(); y = _damping.y(); z = _damping.z(); } const osg::Vec3& getDamping() const { return _damping; } /// Set the velocity cutoff factors void setCutoff( float low, float high ) { _cutoffLow = low; _cutoffHigh = high; } void setCutoffLow( float low ) { _cutoffLow = low; } void setCutoffHigh( float low ) { _cutoffHigh = low; } /// Get the velocity cutoff factors void getCutoff( float& low, float& high ) const { low = _cutoffLow; high = _cutoffHigh; } float getCutoffLow() const { return _cutoffLow; } float getCutoffHigh() const { return _cutoffHigh; } /// Apply the acceleration to a particle. Do not call this method manually. inline void operate( Particle* P, double dt ); protected: virtual ~AngularDampingOperator() {} AngularDampingOperator& operator=( const AngularDampingOperator& ) { return *this; } osg::Vec3 _damping; float _cutoffLow; float _cutoffHigh; }; // INLINE METHODS inline void AngularDampingOperator::operate( Particle* P, double dt ) { const osg::Vec3& vel = P->getAngularVelocity(); float length2 = vel.length2(); if ( length2>=_cutoffLow && length2<=_cutoffHigh ) { osg::Vec3 newvel( vel.x() * (1.0f - (1.0f - _damping.x()) * dt), vel.y() * (1.0f - (1.0f - _damping.y()) * dt), vel.z() * (1.0f - (1.0f - _damping.z()) * dt) ); P->setAngularVelocity( newvel ); } } } #endif