I’ve been getting a good deal of questions about different types of swarming systems in MEL, and I thought I would showcase my GetNClosestObjsFromArray function I developed recently.   Like most of my RVB, MEL, and VB functions, it was originally designed for a specific task which I was developing, but I soon realized it was (and is) very universal.

My initial purpose for this function is to do some CA calculations on 3D swarming systems.  The visualization as well as the behavior of the agents depends upon the proximity of the 3 closest neighbors.  I originally wrote a function just to return the three closest objects (which is on the wiki as well, Get3ClosestObjsFromArray), but that wasn’t challenging enough for me.  🙂

Here it is…

global proc string[] GetNClosestObjsFromArray(string $MainObj, string $OtherArr[], int $NCount) {
//Author Nick Pisca 0001d 2009
string $ClosestArr[];
float $ClosestDistArr[];
float $LocArr[] = `getAttr($MainObj+".translate")`;
vector $LocVec = <<$LocArr[0], $LocArr[1], $LocArr[2]>>;
for($e=0;$e<$NCount;$e++) {
$ClosestDistArr[$e] = 999999999;
for ($xx=0;$xx
float $OppArr[] = `getAttr($OtherArr[$xx]+".translate")`;
vector $OppVec = <<$OppArr[0], $OppArr[1], $OppArr[2]>>;
vector $Diff = $LocVec - $OppVec;
float $DiffDist = mag($Diff);
int $BiggestIndex = GetBiggestFloatIndex($ClosestDistArr);
if ($DiffDist < $ClosestDistArr[$BiggestIndex] && $DiffDist != 0) {
$ClosestDistArr[$BiggestIndex] = $DiffDist;
$ClosestArr[$BiggestIndex] = $OtherArr[$xx];
return $ClosestArr;


Here’s the breakdown:

First off, the inputs are pretty universal and simple:  An object in 3d, the list of all 3d objects, and the number of objects you want to return.  Users need to establish an array of closest distances, hence the ClosestDistArr variable.  This has a variable length, since it’s anticipating any possible number of closest objects.  This is cleared then replaced with the largest possible number in MEL for every index of count N.

Later, the main object is queried for its translation vector–note, it may be more productive or accurate to use the objects cv or vtx values, since pointPosition always retrieves the correct world space coordinate.  Translation does not always give you the correct position, especially if there are rotations, scales, and/or CV manipulation in the previous parts of the generation code.  Regardless, if you are sure that translation is occuring correctly, this code will functions properly for your needs.

Lastly, for each object in the list array, the location is checked against the LocVec.  As each distance is calculated, if the magnitude of the difference vector is smaller than any one of the ClosestDistArr elements, it replaces the largest element.  After the completion of the loop, the function returns an array of pre-determined length with strings of the names of the closest N number of objects.  Pretty cool huh?  🙂

Nick Pisca Particle Skin System, 2009

Nick Pisca Particle Skin System, 2009