I will model how bees swarm flying against the wind. The particle system should model the bees bobbing up, down, in and out. This particle system may eventually be incorporated in my "Man Runs From Bees" animation. This animation contains a scene in which a man will run past the hive, bumping it slightly causing all the bees to come out. Some will chase the man, while other bees will remain, circling around the hive.
The model will consist of two main types of objects: The hive and the bees. For this animation the hive will not change in any way. All of the motion will be in the bees flying in front of the hive. No external forces will act on the bees other than an internal instinct to stay near the hive.
class ParticleIVNode { public: ParticleIVNode(SoSeparator *inst, SoSeparator *parentSep); SoSeparator *getRootSep() { return subGraphRoot; }; SoMaterial *getMaterial() { return material; }; SoTransform *getTransform() { return transform; }; SoSeparator *getInstance() { return instance; }; private: SoSeparator *subGraphRoot; SoMaterial *material; SoTransform *transform; SoSeparator *instance; }; class PropertyStats { public: // Constructors PropertyStats() { name = "null", type = DYNAMIC, mean = 0.0; variance = 1.0; probType = UNIFORM; }; PropertyStats( char *propName, ChangeType changeType, PropType meanValue, PropType varianceValue, ProbDistrType pType ) { name = strdup(propName); type = changeType; mean = meanValue; variance = varianceValue; probType = pType; }; // set/get member access functions // name and type may only be set by constructor void setMean( PropType meanValue ) { mean = meanValue; }; void setVariance( PropType varianceValue ) { variance = varianceValue; }; void setProbType( ProbDistrType probTypeValue ) { probType = probTypeValue; }; const char *getName() { return name; }; ChangeType getChangeType() { return type; }; PropType getMean() { return mean; }; PropType getVariance() { return variance; }; ProbDistrType getProbType() { return probType; }; // return random sample PropType getSample(); private: char *name; // string name of this property ChangeType type; // STATIC or DYNAMIC PropType mean; // constant mean value (mean) PropType variance; // variance value added to mean, scaled by // probability (variance) Prty( PropertyStats *initialProperty ) { prop = initialProperty; }; void setValue( PropType newValue ) { value = newValue; }; PropType getValue() { return value; }; // update using PropertyStats object void update(); private: PropertyStats *prop; // property statistics object for this // object's initial and update values PropType value; // current value of property }; }; class Particle { public: // Constructor Particle(TimeType time, ParticleSystem* thePS, Particle *myParent); // Member access ParticleIVNode *getIVnode() { return IVnode; }; // update all properties void update(TimeType time); // handle death of child void ChildDies (int numKids, Particle* kids[]); // change parent of particle void NewParent (Particle* mommy); private: ParticleSystem* ps; // ptr. to main Particle Sys. ParticleIVNode* IVnode; // ptr. to root node of // Inventor scene sub-graph // for this particle int generatit number children int maxChildren; // maximum number children Particle** child; // array of ptrs to children Particle* parent; // ptr. to parent particle int numProperties; // number of properties PropertyValue props[MAX_PROPS]; // array of properties float trans_array[3]; // x/y/z translation values float rot_array[3]; // x/y/z rotation values void copyProperties(); // Copy Property values to // Inventor node fields void copyProperties2(); // Copy Property values to // Inventor node fields }; class ParticleSystem { public: // Constructor ParticleSystem( char *propsFilename ); // Member access functions int getInitFlag() { return initializeOK; }; SoSeparator *getSceneRoot() { return IVroot; }; SoSeparator *getInstance() { return instance; }; PropertyStats *getProperty(int index) { return &props[index]; }; // Set new instance sub-graph void setInstance(SoSeparator *newInstance) { instance = newInstance; }; // Particle system update function void update(TimeType time); private: int initializeOK; // flag to signal init. OK SoSeparator* IVroot; // root of IV scene graph SoSeparator* instance; // Inventor sub-graph for // particle instance geometry Particle* rootParticle; // initial particle in system int numProperties; // number of property values PropertyStats props[MAX_PROPS]; // array of system Property // values };
There will not be anything particularly special about how the particles are rendered. Each particle is made from simple Inventor nodes and do not require any special processing.