Accessing Particle System Data [MEL]



 

 

 

Particle Systems consist of groups of nodes. Some nodes will be particle emitters, some particle shapes, and there may also be a number of dynamics fields.

The simplest possible case is that shown in the graph above. A single emitter outputs new particles into the particle shape node. The particle shape node will be parented under it's own transform and will be connected to a particle shading engine.

Both the emitter and particle shape nodes take input from the global time node "time1". There is only one instance of a time node in maya, so you can assume they will always be connected to time1.

 

 

 

 

 

 

A more common particle system may be something like the graph above. In this case, there is an additional gravity field which affects the particles contained within the particle shape.

Usually you will find that a particle system consists of a number of different dynamics effects, each one to simulate a different force upon the particle positions.

In maya it is also worth noting that all emitter types and dynamics fields are derived from transform nodes. They merely affect points contained within a shape.

In all honesty, you are unlikely to be able to reproduce every particle effect possible with maya for your games. You may however either use a limited set of dynamics fields, or simply add your own emitter and field types via a plugin, and maintain the maya tools for editing particle systems.

 

 

 

 

Finding all Particle Shapes
in a Scene

The MFn::kParticle nodes basically store all of the particles present in the particle system. It is possible that the particle system may have a fixed number of particles with no emitters adding in particles. I assume that this won't happen in my code, though you may want to check.

 

All we really need to do to export particle systems is to check for node connections to the particle shape. Any emitter or dynamics field nodes we find can then simply be written out to the file.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


#include<maya/MFnParticleSystem.h>
#include<maya/MItDag.h>
#include<maya/MItDag.h>

// create an iterator to go through all particle shapes
MItDag it(MFn::kParticle);

while(!it.isDone())
{
 

// attach the function set to the object. This really
// only gives access to per-particle attributes,
// not much of interest

MFnParticleSystem
fn(it.item());

// only want non-history items
cout<<"Particles "<< fn.name().asChar() <<endl;

cout << "{\n";

// get a list of connections to the particle shape.
// this will be an array of plugs representing the
// attributes on this kParticle node that are
// connected to other nodes

MPlugArray plugs;
fn.getConnections(plugs);

// loop through each connection
for
(int i=0; i<plugs.length(); ++i) {

 

// get the connections to this attribute
MPlugArray
attrplugs;
plugs[i].connectedTo(attrplugs);

// loop through each attribute connection
for(int j=0;j<attrplugs.length();++j) {

 

MObject obj = attrplugs[j].node();

switch(attrplugs[j].node().apiType()) {

  // air field
case MFn::kAir:
 

OutputAir(obj);
break;

// drag field
case MFn::kDrag:

 

OutputDrag(obj);
break;

// gravity field
case MFn::kGravity:

 

OutputGravity(obj);
break;

// newton field
case MFn::kNewton:

 

OutputNewton(obj);
break;

// radial field
case MFn::kRadial:

 

OutputRadial(obj);
break;

// turbulence field
case MFn::kTurbulence:

 

OutputTurbulence(obj);
break;

// uniform field
case MFn::kUniform:

 

OutputUniform(obj);
break;

// vortex field
case MFn::kVortex:

 

OutputVortex(obj);
break;

// volume axis field
case MFn::kVolumeAxis:

 

OutputVolumeAxis(obj);
break;

// particle emitter
case MFn::kEmitter:

 

OutputEmitter(obj);
break;

default: break;

}

}

}

cout << "}\n";

// get next particle system
it.next();

}



 

Outputting Particle Emitters

 

Particle emitters are derived from transforms and therefore exactly the same method of extracting data as a transform node.

 

What data you choose to extract from the particle emitter is more or less up to you. This will be heavily influenced by what you are choosing to support in your games particle engine.

There is no specific function set for the emitter node, so you will have to access the data by manually querying plugs. For a full definition of the emitters attributes, check the DG node and attribute reference in the Maya documentation.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


#include<maya/MFnDagNode.h>

void OutputEmitter(MObject& obj)
{
 

MFnDagNode fn(obj);

cout << "Emitter " << fn.name().asChar() << "\n";

// emitters are inherited from transform nodes. We may
// as well re-use our transform functions

outputTransformData(obj);
outputParentingInfo(obj);

float f;

// get the rate of particle emission
MPlug plg = fn.findPlug("rate");
plg.getValue(f);
cout<< "\tRate " << f << endl;

// max distance from emitter that particle is emitted
plg = fn.findPlug("maxDistance");
plg.getValue(f);
cout<< "\tmaxDistance " << f << endl;

// min distance from emitter that particle is emitted
plg = fn.findPlug("minDistance");
plg.getValue(f);
cout<< "\tminDistance " << f << endl;

// the direction in which particles are emitted
plg = fn.findPlug("dx");
plg.getValue(f);
cout<< "\tDirection " << f;

plg = fn.findPlug("dy");
plg.getValue(f);
cout<< " " << f;

plg = fn.findPlug("dz");
plg.getValue(f);
cout<< " " << f << endl;

// the spread angle of the particles
plg = fn.findPlug("spread");
plg.getValue(f);
cout<< "\tSpread " << f;

// the initial particle colour
plg = fn.findPlug("pcr");
plg.getValue(f);
cout<< "\tParticleColour " << f;

plg = fn.findPlug("pcg");
plg.getValue(f);
cout<< " " << f;

plg = fn.findPlug("pcb");
plg.getValue(f);
cout<< " " << f << "\n";

}


 

 

 

What Next?

Transformation Data

Dynamics Fields


Animation Data


Animation Curves

index

Rob Bateman [2004]

[HOME] [MEL] [API]