// Copyright (c) 2011 The Foundry Visionmongers Ltd. All Rights Reserved. #include "DDImage/Knob.h" #include "DDImage/Knobs.h" #include "DDImage/ParticleOp.h" #include "DDImage/FlaggingKnobClosure.h" using namespace DD::Image; static const char* const CLASS = "ParticleGravity"; static const char* const HELP = "Apply gravity to the particles. \n" "- can be applied on each or all of the x,y,z axis in both directions.\n" "- is actually more of a directional acceleration node than gravity (it " "can go in directions other than \"down\")."; class ParticleGravity : public ParticleBehaviour { public: ParticleGravity(Node* node) : ParticleBehaviour(node) { } void knobs( Knob_Callback f ) { float kDefaultPositions[] = { 0, 0, 0, // from position 0, -0.1, 0 }; // to position. ParticleBehaviour::knobs(f); PositionVector_knob(f, kDefaultPositions, "strength"); Tooltip(f, "The acceleration to be applied to all particles, expressed in units/frame/frame. " "The direction and magnitude of the vector are applied. The position of the vector " "has no effect.\n" "Gravity affects all particles equally irrespective of mass. For more details " "see Galileo. "); addConditionsKnobs( f ); addDomainKnobs( f ); if (!isLicensed()) set_unlicensed(); } virtual void applyBehaviour( const ParticleContext& context, ParticleSystem* ps ) { Knob* k = knob("strength"); if (!k || !k->positionVectorKnob()) return; PositionVector_KnobI* posVecKnob = k->positionVectorKnob(); OutputContext oc = outputContext(); Vector3 strength = posVecKnob->getTo(oc) - posVecKnob->getFrom(oc); int count = ps->numParticles(); for ( int i = 0; i < count; i++) { if ( conditionsApply( ps, i ) ) { applyAcceleration(ps, i, context, strength); } } } static const Description description; const char* Class() const { return CLASS; } const char* node_help() const { return HELP; } }; static Op* build(Node* node) { return new ParticleGravity(node); } const Op::Description ParticleGravity::description(CLASS, build);