Accessing Particle Information

Previous to version 3.0 of Softimage, .ptp files were used to transfer particle information to mental ray shaders. As of version 3.0, Softimage uses mental ray’s user data format to transfer particle cloud data from Softimage to a mental ray particle rendering shader. You may find this data useful for your own shaders as well.

The particle user data is split into two different userdata blocks: Particle Cloud data and Particle Sprite data.

• The Particle Cloud data holds information on the particle cloud such as number of particles, location/velocity/etc. of each particle. This document describes the exact data structures that comprise the user data.

• The Particle Sprite data holds information on particle sprite sequences. This document does not cover the formats used for this.

Particle Data Types Enumeration

Declaration

typedef enum {
       E3D_PDT_ID,                     // miUlong
       E3D_PDT_POSITION,               // miVector
       E3D_PDT_VELOCITY,               // miVector
       E3D_PDT_SIZE,                   // miScalar
       E3D_PDT_ROTATION,               // miVector
       E3D_PDT_ROTATION_SPEED,         // miVector
       E3D_PDT_SPRITE_ANGLE,           // miScalar
       E3D_PDT_SPRITE_ANGLE_SPEED, // miScalar
       E3D_PDT_COLOR,                  // miColor
       E3D_PDT_UVW,                    // miVector
       E3D_PDT_PATH_LENGTH,            // miScalar
       E3D_PDT_PRESSURE,               // miScalar
       E3D_PDT_DENSITY,                // miScalar
       E3D_PDT_AGE,                    // miUlong
       E3D_PDT_AGE_LIMIT,              // miUlong
       E3D_PDT_SEED,                   // miUlong
       E3D_PDT_SPRITE_ID,              // miUlong
       NB_PARTICLE_DATA_TYPES
} E3DParticleDataType;

An enumeration of the data types that are associated with each particle. The type in the comment column after each data type enumeration is the actual data type used, in mental ray terms.

Particle Cloud User Data Header Block

Declaration

typedef struct {
   miUlong  m_one;
   miUlong  m_nbPartType;
   miUlong  m_offsetPartType;  // In bytes
   miUlong  m_nbData;          // In words
   miUlong  m_offsetData;      // In bytes
   miVector m_vBBoxMin;
   miVector m_vBBoxMax;
   miScalar m_dMotionScale;
   miUlong  m_nNotUsed[ 4 ];
;
} S3DParticleHeaderUD;

S3DParticleHeaderUD defines the header information for the entire particle cloud userdata. It contains information on the number of particle types and the size and location of the particle data.

The head block starts at byte 0 of the user data.

• m_one should be of value 0x00000001. It is used both as a version number and a byteswapping marker. If m_one has the value of 0x01000000 then byteswapping of the entire particle data is required. For future versions this will morph into m_two, with a value of 0x00000002, et cetera. The semantics will remain the same.

• m_nbPartType is the number of particle types and, therefore, particle type blocks in the user data.

• m_offsetPartType is an offset, in bytes, from the start of the user data to the first particle type data block.

• m_nbData is the number of data entries for the particle individual data. Each data entry is 4 bytes long. Each data entry is either miUlong or miScalar (miVector is simply taken as three miScalars).

• m_offsetData is a an offset, in bytes, from the start of the user data to the first data entry.

• m_vBBoxMin is the point defining the minimum coordinate of an axis-aligned bounding box of the entire particle cloud.

• m_vBBoxMax is the point defining the maximum coordinate of an axis-aligned bounding box of the entire particle cloud.

m_dMotionScale is a multiplier to scale the particle velocity values before use (E3D_PDT_VELOCITY, E3D_PDT_ROTATION_SPEED and E3D_PDT_SPRITE_ANGLE_SPEED ). This multiplier will change if motion blur in Softimage is set to evaluate motion SRT for the entire frame.

Example: Accessing the Particle Data Blocks

To access the particle type data blocks:

// in_pHeader is a pointer to the header block.
S3DParticleTypeUD *l_pParTypeUD = (S3DParticleTypeUD *)
    ((miUchar *)in_pHeader + in_pHeader->m_offsetPartType);

for(i = 0; i < in_pHeader->m_nbPartType; i++) {
    mi_info( “Number of particles for type %d: %d\n”, 
        i, l_pParTypeUD[ i].m_nbParticles );
}

Particle Type User Data Block

Declaration

typedef struct {
   miUlong    m_nbParticles;
   miUlong    m_shaderIndex;
   miUlong    m_dupeFlag;
   miUlong    m_offset[ NB_PARTICLE_DATA_TYPES ];
   miUlong    m_nNotUsed[ 4 ];
} S3DParticleTypeUD;

• m_nbParticles specifies the number of particles for this type.

• m_shaderIndex is an index into a shader used by this type. DO NOT USE.

• m_dupeFlag is a bit field indicating which data types are identical for every particle associated with this type. If a type’s bit is set then only one data entry is defined for the entire particle range. To check which bits are set use the value one, shifed left by the type enumeration value. For example to check whether the sprite angle is the same across the entire range, use this expression:

       m_dupeFlag & ( 1 << E3D_PDT_SPRITE_ANGLE )

• m_offset[] is an array of offsets, for each data type, into the start of their definitions in the user data. The offsets are defined in bytes relative to the start of the userdata. For example to retrieve the offset to the rotation speed data use: m_offset[E3D_PDT_ROTATION ].

Examples: Retrieving a Specific Value

To retrieve a specific value for a particle use this function. Cast the resulting pointer into the data type you’re interested (see E3DParticleDataType for more information):

void *getDataValue( 
       int in_nParticle,         // Index of particle to get data for
       int in_nParType,         // Particle type the particle lives in
       int in_nDataType,        // Data type (from E3DParticleDataType)
       int in_nDataSize,         // Size of the data type
       S3DParticleHeaderUD *in_pParHeaderUD;
) {
       S3DParticleTypeUD *l_pParTypeUD;
       miUchar *l_pData;

       // Get the required pointers.
       l_pParTypeUD = ( S3DParticleTypeUD *)
       ((miUchar *) in_pParHeaderUD + in_pParHeaderUD->m_offsetPartType );
       l_pParTypeUD = &l_pParTypeUD[ in_nParType ];

       // Get a pointer into the block of data for this data type on the
       // given particle type.
       l_pData = (miUchar *) in_pParHeaderUD + 
              l_pParTypeUD->m_offset[ in_nDataType ];

       // If type is duplicated, always return the zeroth entry
       if( l_pParTypeUD->m_dupeFlags & ( 1 << in_nDataType ) )
          return( &l_pData[ 0 ] );

       // Otherwise return the actual data pointer
       return( &l_pData[in_nParticle * in_nDataSize ] );
}

Retrieving the User Data Block

To retrieve the userdata block we need to get the instance item from the instance given in miState->instance.

The magic number of that user data is 0xF00D.

Example: Retrieving the User Data Block

This example assumes that the userdata lives on the item of the instance given with the current hit point.

S3DParticleHeaderUD * findUserData( 
       miState *in_pMI, 
       miTag  in_tInstance ) 
{
       miTag  l_tUserData, l_tObject;
       miUint l_label;


       // Get the item tag and the item’s userdata block tag.
       mi_query(miQ_INST_ITEM, in_pMI, in_tInstance, (void *)&l_tObject);
       mi_query(miQ_OBJ_DATA, in_pMI, l_tObject, (void *)&l_tUserData);

       for(;;) {
          l_label = 0;

          // Couldn’t retrieve a label. Exit.
          if(!mi_query(miQ_DATA_LABEL, in_pMI, l_tUserData, &l_label))
              break;

          // Is it a particle cloud data?
          if( l_label == 0xF00D ) {
              S3DParticleHeaderUD *l_pData = NULL;

              // Return the data pointer if found
              if(mi_query(miQ_DATA_PARAM, NULL, l_tUserData, 
                                       (void*)&l_pData))
                 return( l_pData );
          }
          // Get the next data block
          if(!mi_query(miQ_DATA_NEXT, in_pMI, l_tUserData, &l_tUserData))
              break;
       }
       return( NULL );


Autodesk Softimage v7.5