Table of Contents
Input Group Functions
The Group input of the ExpressionME-L Node enables efficient parallel processing of particle data. When this input is created as the first input, all connected node data will be processed using multi-threading. If the Group input is not the first input, it will be processed in a single threaded, serial manner.
A variety of powerful functions are available for reading specific particle data. You can also choose to include or exclude subgroups in the evaluation process. When subgroups are included, all particles will be treated as if they were in a single combined pool.
Global Variables
Variable | Description |
---|---|
group_in_count | The number of particles in the current group. This also works with virtual ME-L Groups |
group_in_id | returns the index of the input you created (starting with 0 excluding Time and On). This also works with virtual ME-L Groups |
Note, particle count is a variable and not a function. It is directly accessible through the given input name that has been created. See example below:
Accessing particle count in any given group:
// IO Block Start input_desc('bysize', port_mgroup); %%//%% create a internal Group called bysize input_desc('dust', port_group); %%//%% create a tP particle Group input called dust / IO Block End // accessing the dust group particles for(var i = 0; i < dust_in_count; i += 1) {\\ pid=group_in_id2pid(i); ..do something }; for(var i = 0; i < bysize_in_count; i += 1) { pid=group_in_id2pid(i); ..do something };
group_in_id2pid
The group_in_id2pid function is used to convert a particle ID within a group to a real thinkingParticles (tP) particle ID. Particle Groups are like containers that can store a large number of particles. These particles can either be created within the group or moved into it. Each particle has its own internal ID that is used to address or affect the exact particle within thinkingParticles. This function is used to retrieve the system-wide ID of a particle within a group.
Example:
Every particle group can collect and hold particles in any way possible. Within each group, particles are arranged in a simple linear list ordered by creation, from 0 to the maximum number of particles in the group. To retrieve the unique internal particle ID, used by thinkingParticles internally, you can call this function. For example, to get the unique ID of particle 17, you would call realid=group_in_id2pid(17)
and this function would return perhaps ID:376895 which is the particle known to tP.
Call:
group_in_id2pid(in_id)
Parameters
Parameter | Description |
---|---|
in_id | Group particle id. |
Output:
Return | Description |
---|---|
scalar | Returns the particle ID |
Code Example:
go through all particles in the group
var pid; var ppos[3]; for(var i = 0; i < group_in_count; i += 1) { pid=group_in_id2pid(i); ..as sample get the position from the pid get_pdata(pid, data_pos, ppos); };
group_in_find
used to search for particles within a given radius of a specified world position in a group.
Call:
group_in_find(world_position, radius, max_found, optional skip_particleid)
This function has the following parameters:
Parameter | Description |
---|---|
world_position | a 3-element array specifying the world position to search around |
radius | a scalar value specifying the radius to search within |
max_found | sets the maximum particles to search for |
skip_particleid (optional) | a particle ID to skip from the found list. This can be used to avoid finding the local particle itself. |
Return:
The function returns a scalar value indicating the number of particles found.
group_in_find_data
Gathers any particle data from a set of found particles within a group. This function only makes sense, when group_in _find
returned a result to iterate over.
Call:
group_in_find_data(id, find_type, ret_value)
Parameter | Description |
---|---|
id | The index (0 based) of the found particle (as returned by group_in_find ), this is used to gather particle data |
find_type | The type of data to gather |
ret_value | The variable to store the data, scalar or a vector[3] |
Return:
If the function returns 0, it means there was no data and the value of ret_value
will be unspecified. If the function returns 1, it means that access to the data was successful and ret_value
has been set to the gathered data.
Data Type | Description |
---|---|
find_pid | Return the Particle id that was found |
find_dist2 | Square distance |
find_dist | Distance |
find_dif | Difference Vector from search position to found particle position |
find_dir | Direction to find particle position |
find_mcenter | Calculates the Center of Mass of particles found |
find_vel_average | Calculates the average velocity of particles found |
find_vel_maverage | Calculates the average velocity weighted by mass of particles found |
Usage:
To find the maximum of 5 particles at position (0,0,0) with a radius of 10 in the input group2, you can use the following code:
var pos[3] = {0,0,0}; var found = group2_in_find(pos, 10, 5); if(found > 0) { var pid2; var pvel2[3]; var dir; //iterate through the found data for (var i := 0; i < found; i += 1) { pgroup2_in_find_data(i, find_pid, pid2); //get the find pid\\ pgroup2_in_find_data(i, find_dir, dir); //get the find direction get_pdata(pid2, data_vel , pvel2); //get the velocity from the find pid ......%%//%%do anything with the found data }; };
Explanation:
- The
group2_in_find
function is called with the search position (0,0,0), the radius (10) and the maximum number of particles to find (5). - If the function returns a value greater than 0, it means that at least one particle was found.
- The loop iterates through the found particles and calls the
pgroup2_in_find_data
function to get the particle ID of the found particles and gets the particles's direction. - The
get_pdata
function is called to get the velocity of the particle with idpid2
.
group_in_create
this function is used to create a new particle at a specified position. When the first input of the ME-L Expression node is a particle group, at least one particle needs to be present to execute this function.
Be careful not to create particles into the same group or you will end up with exponentionally creating particles of particles of particles …
Call:
group_in_create(pos, optional velocity)
Parameter | Description |
---|---|
pos | vector[3] world position of the new particle |
vel (Optional) | vector[3] the initial velocity of the new particle |
Output:
Return | Description |
---|---|
scalar | returns either a new particle id or -1 on fail |
group_in_isect
This function intersects all particle shapes in a group.
Call:
group_in_isect(pos, dir, max_length, optional pskip, optional fskip)
Parameters:
Parameter | Description |
---|---|
pos | intersect ray start point (vector) |
dir | intersect ray direction (normalized or with length) (vector) |
max_length | intersect max ray length (scalar) |
pskip | optional particle to skip (scalar) |
fskip | optional face of the particle to skip (scalar) |
Output:
Return | Description |
---|---|
scalar | 0: not intersected, 1: frontside, -1: backside hit |
group_in_isect_data
This function gets the hit data of a group intersection. It is only valid after a group_in_isect result
is not equal to 0.
Call:
group_in_isect_data(isect_data, vector_out[3])\\ group_in_isect_data(isect_data, scalar_out)\\ group_in_isect_data(isect_uvw, chan, uvw_out)
Parameters:
Parameter | Description |
---|---|
isect_data | the hit point data to specify the data to retrieve. |
vector_out | vector output |
scalar_out | scalar output |
chan | the interpolated UVW coordinate from channel 0-99 (scalar) |
uvw_out | UVW coordinates (vector) |
The isect_data
object includes the following possible properties:
Parameter | Description |
---|---|
point_pid | Particle id (scalar) |
point_pos | World position (vector) |
point_opos | Object position (vector) |
point_dist | Hit distance (scalar) |
point_norm | World surface normal (vector) |
point_onorm | Object surface normal (vector) |
point_gnorm | World geometry normal (vector) |
point_ognorm | Object geometry normal (vector) |
point_dot | The dot product is the cosine of the hit angle to the normal (scalar) |
point_backside | Is a backside hit (scalar) |
point_uvw | UVW coordinates (vector) |
point_mtlid | Material id (scalar) |
point_fid | Face id (scalar) |
point_bc | Barycentric coordinates (vector) |
point_color | Material color (vector) |
point_vel | World particle velocity on the hit point (includes spinning) (vector) |
point_center | World center of the intersected particle |
Output:
Return | Description |
---|---|
scalar | 0: no data available, 1: data available |
Example:
if(pgroup2_in_isect(wp, pvel*dt, 1.0)) { pgroup2_in_isect_data(point_norm, dir); pgroup2_in_isect_data(point_vel, vel); dprod = dot(dir, pvel - vel); if(dprod < 0) { pvel = pvel - dir * (dprod * bounce_in); set_pdata(pid, data_vel , pvel); pgroup2_in_isect_data(point_col, color); set_pdata(pid, data_dchan+1, color); } else dprod = 0; };
Explanation:
This code example checks for intersections between a particle group and a ray, and modifies the velocity and color of the particles in the group based on the result of the intersection.
The code first calls the pgroup2_in_isect
function, passing in the wp
(world position) of the particle, the velocity of the particle multiplied by dt
(delta time), and a maximum length of 1.0. If this function returns true, indicating that an intersection occurred, the code proceeds to retrieve data about the intersection using the pgroup2_in_isect_data
function.
The pgroup2_in_isect_data
function is called twice, the first time with the point_norm
parameter and the dir
variable as output, and the second time with the point_vel
parameter and the vel
variable as output. These calls retrieve the surface normal and velocity of the particle at the point of intersection.
The code then calculates the dot product of the surface normal and the difference between the particle's velocity and the vel
variable. If this dot product is negative, the code modifies the particle's velocity by subtracting the surface normal multiplied by the dot product and the bounce_in
variable. It then sets the modified velocity back to the particle using the set_pdata
function, and sets the particle's color to the color
variable using the set_pdata
function as well. If the dot product is not negative, it is set to 0.
Functions to Manage virtual ME-L Groups
ME-L groups behave similarly to thinkingParticles' own particle groups, with the exception that they do not have a hierarchy. The same particle can be in several groups. Virtual ME-L groups are accessible throughout multiple ME-L nodes, either in one or many DynamicSets. Accessing virtual ME-L Groups between multiple nodes is done via a strict naming convention. By using the identical name in every ME-L Node, the same group properties will be shared as well.
As with any Node input, when the first input is an ME-L group, the data stored within will be processed in a multi-threaded parallel manner.
mgroup_in_add
Adds a particle to the virtual ME-L group. Multiple calls with the same ID, will not add the same particle twice to this group.
Call:
mgroup_in_add(particle_id_in);
Return:
The function returns a scalar >=0 for a valid particle ID, -1 for no particle ID
mgroup_in_remove
Removes a particle from the virtual ME-L Group
Call:
mgroup_in_remove(particle_id_in);
Return:
The function returns a scalar >=0 for a valid particle ID, -1 for no particle ID
mgroup_in_ingroup
Checks if a particle is part of a virtual ME-L Group
Call:
mgroup_in_ingroup(particle_id_in);
Return:
The function returns a scalar >=0 for a valid particle ID, -1 for no particle ID
ME-L virtual Group Examples**: Go manually through all particles in a ME-L Group
for(var i = 0; i < mgroup_in_count; i+= 1) { pid = mgroup_in_id2pid(i); if(pid >= 0) { ..... do something } }
= ©2024, cebas Visual Technology Inc. =