vsPiotr
09-23-2009, 03:13 PM
Hi All,
Trying to get some dynamics into a shatter effect with 1000+ elements
I came up with a script that creates nParticles at selected geometry centers and then connects the geo to each particle via expressions so that you can do some quick dynamics on the particle rather than the whole object. (good when lots of small objects).
Just wondering if there's a better way?
I tried using rigid bodies and felt a lot slower (also now I can use nCache etc). is there a way to tell rigid to only use a sphere or a stand in etc rather than whole mesh?
for any one interested, here's my mel:
//Bind objects to nParticles
string $selection[] = `ls -sl`;
int $n = 0;
float $partPos[];
string $particleList = "nParticle";
for ($sel in $selection){
float $p[] = `xform -ws -q -rp $sel`;
xform -a -ws -t (-1*$p[0]) (-1*$p[1]) (-1*$p[2]) $sel;
makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 $sel;
xform -t $p[0] $p[1] $p[2] $sel;
$particleList = $particleList + " -p " + $p[0] + " " + $p[1] + " " + $p[2];
if(`attributeQuery -node $sel -ex "particleIndex"` != 1){
addAttr -longName "particleIndex" -at "short" $sel;
}
setAttr ($sel + ".particleIndex") $n;
$n++;
}
string $nParticleShape[] = eval($particleList);
for($sel in $selection){
float $w = `getAttr ($sel + ".boundingBoxSizeX")`;
float $h = `getAttr ($sel + ".boundingBoxSizeY")`;
float $d = `getAttr ($sel + ".boundingBoxSizeZ")`;
float $bbox[] = {$w, $h, $d};
float $dim = 0;
if($w>$dim){ $dim = $w;};
if($h>$dim){ $dim = $h;};
if($d>$dim){ $dim = $d;};
$dim = $dim * 0.25;
int $particleIndex = `getAttr ($sel + ".particleIndex")`;
//nParticle -e -attribute radiusPP -order $particleIndex -fv $dim $nParticleShape[1];
string $expr = "float $pos[] = `nParticle -attribute position -order " +
$particleIndex +
"-q nParticleShape1`;\n" +
"translateX = $pos[0];\n" +
"translateY = $pos[1];\n" +
"translateZ = $pos[2];\n" +
"float $vel[] = " +
"`nParticle -attribute velocity -order " +
$particleIndex + " -q nParticleShape1`;\n" +
"if(`currentTime -q` > 1){\n" +
"rotateX = rotateX + ($vel[0]/10);\n" +
"rotateY = rotateY + ($vel[1]/10);\n" +
"rotateZ = rotateZ + ($vel[2]/10);\n" +
"}else{\n" +
"rotateX = 0;\n" +
"rotateY = 0;\n" +
"rotateZ = 0;\n" +
"}\n";
expression -s $expr -o $sel -ae 1 -uc all;
}
I started writing some provisions to alter radiusPP according to geo bounding box. not working yet.
Trying to get some dynamics into a shatter effect with 1000+ elements
I came up with a script that creates nParticles at selected geometry centers and then connects the geo to each particle via expressions so that you can do some quick dynamics on the particle rather than the whole object. (good when lots of small objects).
Just wondering if there's a better way?
I tried using rigid bodies and felt a lot slower (also now I can use nCache etc). is there a way to tell rigid to only use a sphere or a stand in etc rather than whole mesh?
for any one interested, here's my mel:
//Bind objects to nParticles
string $selection[] = `ls -sl`;
int $n = 0;
float $partPos[];
string $particleList = "nParticle";
for ($sel in $selection){
float $p[] = `xform -ws -q -rp $sel`;
xform -a -ws -t (-1*$p[0]) (-1*$p[1]) (-1*$p[2]) $sel;
makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 $sel;
xform -t $p[0] $p[1] $p[2] $sel;
$particleList = $particleList + " -p " + $p[0] + " " + $p[1] + " " + $p[2];
if(`attributeQuery -node $sel -ex "particleIndex"` != 1){
addAttr -longName "particleIndex" -at "short" $sel;
}
setAttr ($sel + ".particleIndex") $n;
$n++;
}
string $nParticleShape[] = eval($particleList);
for($sel in $selection){
float $w = `getAttr ($sel + ".boundingBoxSizeX")`;
float $h = `getAttr ($sel + ".boundingBoxSizeY")`;
float $d = `getAttr ($sel + ".boundingBoxSizeZ")`;
float $bbox[] = {$w, $h, $d};
float $dim = 0;
if($w>$dim){ $dim = $w;};
if($h>$dim){ $dim = $h;};
if($d>$dim){ $dim = $d;};
$dim = $dim * 0.25;
int $particleIndex = `getAttr ($sel + ".particleIndex")`;
//nParticle -e -attribute radiusPP -order $particleIndex -fv $dim $nParticleShape[1];
string $expr = "float $pos[] = `nParticle -attribute position -order " +
$particleIndex +
"-q nParticleShape1`;\n" +
"translateX = $pos[0];\n" +
"translateY = $pos[1];\n" +
"translateZ = $pos[2];\n" +
"float $vel[] = " +
"`nParticle -attribute velocity -order " +
$particleIndex + " -q nParticleShape1`;\n" +
"if(`currentTime -q` > 1){\n" +
"rotateX = rotateX + ($vel[0]/10);\n" +
"rotateY = rotateY + ($vel[1]/10);\n" +
"rotateZ = rotateZ + ($vel[2]/10);\n" +
"}else{\n" +
"rotateX = 0;\n" +
"rotateY = 0;\n" +
"rotateZ = 0;\n" +
"}\n";
expression -s $expr -o $sel -ae 1 -uc all;
}
I started writing some provisions to alter radiusPP according to geo bounding box. not working yet.
