PDA

View Full Version : LOD script


Bonedaddy
02-08-2004, 12:47 AM
Hey all,

I have never coded in MEL before, so all of this is still very, very confusing for me, but I have great need of a LOD script that works with Mental Ray (Maya's default does not). Thus, I'm learning.

I've managed to get a script together that will tell me the distance from the camera of an object, if I specify the object's name. From there, I plan on setting a threshhold, and if the distance crosses that threshhold, to turn off the visibility of one object and turning on the visibility of another.
However, to implement this, I have some questions:

1) How would I set this up so that it's, for lack of a better word, habitual? So that it evaluates every time the camera or object's position changes? Would I use the Expression Editor, rig something up there? Or am I barking up the wrong tree?
2) I have to do this with a large number of objects (basically a forest blanketing several mountains, one for each tree), so how should I configure it to easily keep tabs on which objects are affected by this? I realize that naming is going to be a big thing (oak1_heavy and oak1_card, for example), but still, would appreciate any thoughts, insights people had.



Thanks much for any help anyone can provide. I'd be happy if I could just get the LOD packaged with Maya to work, but whatever it's doing to make the objects invisible doesn't work in Mental Ray...

Bonedaddy
02-08-2004, 12:48 AM
Here's what I got so far, that gets the distance between camera and another object. It's set to pCube1 for tests. I realize it's probably fairly inelegant, but I'm thrilled it even works... :)

float $camPos[3]=`xform -q -t persp`;
float $objPos[3]=`xform -q -t pCube1`;
float $distx=$camPos[0]-$objPos[0];
float $disty=$camPos[1]-$objPos[1];
float $distz=$camPos[2]-$objPos[2];
vector $distance=<<$distx, $disty, $distz>>;
float $magnitude=mag($distance);

Bonedaddy
02-08-2004, 04:29 AM
Genius!
Well, not entirely. But I got it to work. What I ended up doing is setting up my scene so that all the trees have two copies, same name with _hi and _lo at the end of it. They are grouped together in a normal group.
All the lod'd groups, in turn, are grouped underneath a larger group, in this code known as group1.
This took me FOREVER to get going, but I am very pleased that it works. I'm sure it's incredibly rough, and has plenty of sloppy code, so if anyone has any suggestions, by all means, make em! I'd like to learn more, certainly!





proc float jpo_getDistance(string $object) {
string $jpo_camera="persp";
float $camPos[3]=`xform -q -t $jpo_camera`;
float $objPos[3]=`xform -q -t $object`;
float $distx=$camPos[0]-$objPos[0];
float $disty=$camPos[1]-$objPos[1];
float $distz=$camPos[2]-$objPos[2];
vector $distance=<<$distx, $disty, $distz>>;
float $magnitude=mag($distance);
return $magnitude;
}


proc jpo_lod_change() {
float $threshhold=50;
string $children[]=`listRelatives -c -type "transform" group1`;
int $i;
for ($i = 0; $i < size($children); $i++) { //iterate through groups of
string $resolutionarray[]=`listRelatives -c -type "transform" $children[$i]`;
int $j;
if (size($resolutionarray)) { //if the object inside bigGroup is a lod_group
for ($j = 0; $j < size($resolutionarray); $j++) {
string $buffer[];
tokenize $resolutionarray[$j] "_" $buffer;
float $distance=jpo_getDistance($resolutionarray[$j]);
print("Distance is " + $distance);
if ($distance>$threshhold) { //over threshhold, turn to low lod
if ($buffer[size($buffer)-1]=="lo") { //if this object is low resolution
setAttr ($resolutionarray[$j] + ".visibility") 1;
}
if ($buffer[size($buffer)-1]=="hi") { //if this object is high resolution
setAttr ($resolutionarray[$j] + ".visibility") 0;
}
}
else { //if under threshhold
if ($buffer[size($buffer)-1]=="hi") { //if this object is high resolution
setAttr ($resolutionarray[$j] + ".visibility") 1;
}
if ($buffer[size($buffer)-1]=="lo") { //if this object is low resolution
setAttr ($resolutionarray[$j] + ".visibility") 0;
}
}
}
}
}

}

Bonedaddy
02-08-2004, 04:35 AM
Except, of course, it won't work on instances, because instances all share the same shape node. Gahh... how to turn off the visibility for just instances... maybe I can hide them...

Bonedaddy
02-08-2004, 05:19 AM
Alright, so what I CAN do to hide instances is to give them each an individual grouping (i.e. another transform node controlling their visibility above the shape node and below the lod_group node, and below the bigGroup node). If I do that, it's going to get incredibly messy. All in the name of render times, I suppose...

sbp
02-08-2004, 02:27 PM
That's pretty good, but you don't have to reinvent the wheel, at least in 4.5. I don't know if 5 is different. The lodGroup is still valid, it's just MR doesn't use it to establish visibility so all you need is something like this.

string $lg[] = `ls -type lodGroup`;
for ($a in $lg)
{
float $gv[] = `getAttr ($a + ".o")`;
string $gn[] = `listConnections -type transform $a`;
int $i;
for ($i = 0; $i < size($gn); $i++)
eval ("setAttr " + $gn[$i] + ".v " + $gv[$i] );
}

You may or may not have to adjust for a naming convention, it depends on how you work.

CGTalk Moderation
01-17-2006, 10:00 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.