Skocz do zawartości

Problem przy rigu


guzikk

Rekomendowane odpowiedzi

Przy orient constrain circle i bone, bone obraca się o -180, 180, -180. O co chodzi? Nie mam pojęcia skąd się to bierze tym bardziej że przy prawym odpowiedniku owej kości tego problemu nie było. Może to kwestia złego mirrora?

Odnośnik do komentarza
Udostępnij na innych stronach

  • Odpowiedzi 14
  • Created
  • Ostatniej odpowiedzi

Top Posters In This Topic

prawdopodobnie jest to kwestia tego że bone i circle mają całkowicie różne przestrzeni transformacji. Jak jeszcze rigowałem swego czasu w Maya to obchodziłem to w ten sposób że kontrolery dla kości przygotowywałem tak że najpierw tworzyłem transform node (albo group się to nazywało), kopiowałem mu macierz kości po czym linkowałem atrybuty (ma to swoją taką zaletę że nie używa się orient constraint, który jest znacznie bardziej zasobożerny niż connectAttr. Generalnie popatrz sobie jak wyglądają lokalne osie obiektów.

Odnośnik do komentarza
Udostępnij na innych stronach

pewnie mirrorowałeś kości z zaznaczonym Behavior a nie Orientation. I niestety pewnie tak musisz zrobić. Jeśli bardzo CI to przeszkadza, to:

1. zgrupuj obiekt który ma orientConstraint,

2. wyrównaj pivoty grup

3. obróć grupę o właściwe wartości tak, żeby kanały z orientem się wyzerowały

Odnośnik do komentarza
Udostępnij na innych stronach

Tu jednak chodzi chyba faktycznie o to na co wskazuje Kroopson. Zrobiłem parę doświadczeń i faktycznie wyszło że to nie zależy od mirrora tylko od fragmentu przestrzeni na której działam.

a zatem Kroopson móglbyś konkretniej wyjaśnić co masz na myśli?

Odnośnik do komentarza
Udostępnij na innych stronach

Ja bym tu sprobowal wyrownac kolejnosc rotacji wszystkich jointow po jednej stronie

i odwrocic po drugiej (opcją orient joints).

A jesli nie pomoze to moze wstaw sobie dodatkowy locator miedzy kosciami odwracajacy transformacje.

Pozdr.

Odnośnik do komentarza
Udostępnij na innych stronach

if(`window -exists "addFKControl"`)
deleteUI "addFKControl";

if(`windowPref -exists "addFKControl")
windowPref -r "addFKControl";

// Prepare the UI

window -rtf true -title "Add FK Controller" addFKControl;
columnLayout -rowSpacing 5 addFKControlColumn1;
	intSliderGrp -label "Number of sides" -field true -minValue 3 -maxValue 32 -value 4 FKnumber;
	intSliderGrp -label "Height divisions" -field true -minValue 1 -maxValue 32 -value 1 FKheight;
	floatSliderGrp -label "Radius" -field true -minValue .0001 -maxValue 2 -value 1 FKradius;
	text -label "Controller Orientation";
	separator -ann "Controller Orientation" -w 250;
	radioCollection addFKRadioGrp1;
	rowLayout -numberOfColumns 3 addFKControlRow1;
			radioButton -label "+X" posX;
			radioButton -label "+Y" posY;
			radioButton -label "+Z" posZ;
	setParent ..;
	rowLayout -numberOfColumns 3 addFKControlRow2;
			radioButton -label "-X" negX;
			radioButton -label "-Y" negY;
			radioButton -label "-Z" negZ;
	setParent ..;
	separator -w 250;
	button -c "addFKControlPrep" -label "Create";
setParent ..;
showWindow addFKControl;

radioCollection -e -sl posX addFKRadioGrp1;

// Preparation phase

global proc addFKControlPrep(){
$sel = `ls -sl`;
string $a;
float $length;

// See if we have anything selected

if (size($sel) == 0){
	error "Select a target";
}

// Recurence trough selection

for($a in $sel){

		$child = `listRelatives -c $a`;

		if (size($child) > 0 && nodeType($child[0]) == "joint"){	// If the target is a joint calculate the length
			float $componentX = `getAttr ($child[0] + ".tx")`;
			float $componentY = `getAttr ($child[0] + ".ty")`;
			float $componentZ = `getAttr ($child[0] + ".tz")`;
			$length = `mag (>)`; 
		} else {													// If not - set length to 1
			$length = 1;
		}
	int $nGon = `intSliderGrp -q -value "FKnumber"`;				// Read values
	int $height = `intSliderGrp -q -value "FKheight"`;
	float $rad = `floatSliderGrp -q -value "FKradius"`;
	string $orient = `radioCollection -q -sl addFKRadioGrp1`;
	addFKControl( $nGon, $height, $length, $rad, $a, $orient);		// Make the main function
}
}

global proc string addFKControl ( int $nGon, int $height, float $len , float $radius, string $targetName, string $orient) {

string $name = $targetName + "_FK_control";

float $vertCoords[] = {};
string $command = "curve -d 1 ";
float $step = 360/$nGon;
float $angle = 0 - ($step/2);
string $endcommand = " ";
	for ($a = 0; $a 			$angle +=$step;
		float $resultX = (`cos (deg_to_rad($angle))`) * $radius;
		float $resultY = (`sin (deg_to_rad($angle))`) * $radius;
		$vertCoords[($a*2)] = $resultX;
		$vertCoords[($a*2) + 1] = $resultY;
	}

$vertCoords[$nGon*2] = $vertCoords[0];	
$vertCoords[($nGon*2)+1] = $vertCoords[1];	
for ($n = 0; $n 		float $div = 1.0;
	float $flHeight = ($height/$len) * 1.0;
	int $count = 0;
	for ($a = 0; $a 			float $div = `floor($n/$nGon)`;
		$command += "-p " + $vertCoords[($a*2)] + " " + ($n/$flHeight) + " " + $vertCoords[($a*2) + 1] + " ";
		$command += "-p " + $vertCoords[(($a+1)*2)] + " " + ($n/$flHeight) + " " + $vertCoords[(($a+1)*2) + 1] + " ";
		$command += "-p " + $vertCoords[(($a+1)*2)] + " " + (($n+1)/$flHeight) + " " + $vertCoords[(($a+1)*2) + 1] + " ";
		$command += "-p " + $vertCoords[($a*2)] + " " + (($n+1)/$flHeight) + " " + $vertCoords[($a*2) + 1] + " ";
		$command += "-p " + $vertCoords[($a*2)] + " " + ($n/$flHeight) + " " + $vertCoords[($a*2) + 1] + " ";
		$count = $a;
	}
	$command += "-p " + $vertCoords[($count*2)] + " " + (($n + 1)/$flHeight) + " " + $vertCoords[($count*2) + 1] + " ";

}
$command += $endcommand;
$command += " -n ";
$command += $name;
$curveNode = `eval ($command)`;

$curveNodeShape = `listRelatives -c $curveNode`;
rename $curveNodeShape ($curveNode + "Shape");

if ($orient == "posX"){
	setAttr ($curveNode + ".rotateZ") -90;
	makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 $curveNode;
}
if ($orient == "negX"){
	setAttr ($curveNode + ".rotateZ") 90;
	makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 $curveNode;
}
if ($orient == "negY"){
	setAttr ($curveNode + ".rotateZ") 180;
	makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 $curveNode;
}

if ($orient == "posZ"){
	setAttr ($curveNode + ".rotateX") 90;
	makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 $curveNode;
}
if ($orient == "negZ"){
	setAttr ($curveNode + ".rotateZ") -90;
	makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 $curveNode;
}

$controlOrient = `group -e 1 -n ($targetName + "_FK_control_orient")`;
	setAttr ($controlOrient[0] + ".localScaleX") ($radius / 10);
	setAttr ($controlOrient[0] + ".localScaleY") ($radius / 10);
	setAttr ($controlOrient[0] + ".localScaleZ") ($radius / 10);
parent $curveNode $controlOrient;
copyMatrixAddFK ($targetName, $controlOrient[0], 1);

// Set proper rotation order.

setAttr ($curveNode + ".rotateOrder") (`getAttr ($targetName + ".rotateOrder")`);

return $curveNode;
}

global proc copyMatrixAddFK( string $sourceObj, string $targetObj, int $worldSpace){
string $command;
float $sourceMatrix[];
if($worldSpace == 1){
	$sourceMatrix = `xform -q -ws -m $sourceObj`;
	$command = "xform -ws -m ";
} else {
	$sourceMatrix = `xform -q -os -m $sourceObj`;
	$command = "xform -os -m ";
}

string $matrix;
string $a;
for($a in $sourceMatrix){
	$matrix += $a;
	$matrix += " ";
}

$command += $matrix;
$command += $targetObj;

eval($command);
}

 

Spróbuj sobie użyć tego skryptu. Może będzie działał, nie używałem go niestety od bardzo dawna więc nie ręczę za wyniki. Po zaznaczeniu jointa i odpaleniu tego cuda powinno ci się okienko otworzyć z możliwością stworzenia kontrolera do FK :)

Odnośnik do komentarza
Udostępnij na innych stronach

A jeszcze parę słów na temat tego dlaczego w maya tak się dzieje jak się dzieje. Otóż jointy w Maya mają 2 macierze - jedną zwykłą macierz transformacji oraz drugą - która często się nazywa "joint orient ", i jest ona swego rodzaju pre-transformem, ustawiającym jointa tak, żeby np jego oś X wskazywała na jointy potomne (taką operację dokonuje właśnie funkcja orient joint). Dlatego własnie mówiłem o innej przestrzeni transformacji dla jointów, innej dla kontrolera.

 

Kiedy aplikujesz orient constraint to ten node (orient constraint) operuje w przestrzeni world space - kopiuje macierz rotacji z obiektu znajdującego się w world space do obiektu znajdującego się w zupełnie innej przestrzeni transformacji.

Jeśli masz włączoną opcję "maintaint offset" (mogę nie pamiętać dokładnej nazwy) to Maya będzie musiała skompensować rotację targetu dla constraina przez co ustawia jakąś wartość rotacji na nim (np. 180, 180, 0 itp.).

Spróbuj sobie nałożyć orient constraint z wyłączoną opcją maintaint offset, mając włączone wyświetlanie osi na joincie i na obiekcie kontrolującym jointa - zobacz jak się zachowają.

 

Jeśli chcemy sobie zrobić kontrolki niezależne od jointów (które mogłyby służyć np do kontroli FK) to musimy sobie odtworzyć ten pretransfowm dodając transform node'a będącego rodzicem naszego wymarzonego fk kontrolera. Oczywiście nie jest to jedyna metoda rozwiązania tego problemu ale napewno jest skuteczna.

 

W sumie może wystarczyłoby skopiować transformację jointa i zafreezować transformację na kontrolerze - może to by podziałało.

  • Confused 1
Odnośnik do komentarza
Udostępnij na innych stronach

Co do skryptu:

wyrzuca mi syntax error. Mój ulubiony error z czasów pisania w C ;P. I szukaj tu teraz błędu składni. To ja już wolę Jave ;]

 

Przejżę ten kod i jak znajdę przyczynę erroru to dam znać.

 

 

Serdeczne dzięki za wyjaśnienie problemu - zdecydowanie przyda mi się ta wiedza. Poświęcę jej niebawem więcej uwagi by dokładnie przeanalizować i zrozumieć zagadnienie interakcji constrainta na obiekt constraintowany na tyle dobrze by umieć wytłumaczyć komuś innemu.

Odnośnik do komentarza
Udostępnij na innych stronach

dobra, znalazłem błąd.

 

w 4 linii kodu

if(`windowPref -exists "addFKControl")

 

brakowało gravisa przed nawiasem zamykającym

if(`windowPref -exists "addFKControl"`)

 

 

EDIT

oho, widzę tu więcej błędów. Prawdopodobnie przez to że zmieniły się flagi metod. Postaram się to poprawić i przesłać wersję działającą na aktualnym oprogramowaniu.

Edytowane przez guzikk
Odnośnik do komentarza
Udostępnij na innych stronach

Oto działający kod:

 

if(`window -exists "addFKControl"`)
deleteUI "addFKControl";

if(`windowPref -exists "addFKControl"`)
windowPref -r "addFKControl";



window -rtf true -title "Add FK Controller" addFKControl;
columnLayout -rowSpacing 5 addFKControlColumn1;
	intSliderGrp -label "Number of sides" -field true -minValue 3 -maxValue 32 -value 4 FKnumber;
	intSliderGrp -label "Height divisions" -field true -minValue 1 -maxValue 32 -value 1 FKheight;
	floatSliderGrp -label "Radius" -field true -minValue .0001 -maxValue 2 -value 1 FKradius;
	text -label "Controller Orientation";
	separator -ann "Controller Orientation" -w 250;
	radioCollection addFKRadioGrp1;
	rowLayout -numberOfColumns 3 addFKControlRow1;
			radioButton -label "+X" posX;
			radioButton -label "+Y" posY;
			radioButton -label "+Z" posZ;
	setParent ..;
	rowLayout -numberOfColumns 3 addFKControlRow2;
			radioButton -label "-X" negX;
			radioButton -label "-Y" negY;
			radioButton -label "-Z" negZ;
	setParent ..;
	separator -w 250;
	button -c "addFKControlPrep" -label "Create";
setParent ..;
showWindow addFKControl;

radioCollection -e -sl posX addFKRadioGrp1;

// Preparation phase

global proc addFKControlPrep(){
$sel = `ls -sl`;
string $a;
float $length;

// See if we have anything selected

if (size($sel) == 0){
	error "Select a target";
}

// Recurence trough selection

for($a in $sel){

		$child = `listRelatives -c $a`;

		if (size($child) > 0 && nodeType($child[0]) == "joint"){	// If the target is a joint calculate the length
			float $componentX = `getAttr ($child[0] + ".tx")`;
			float $componentY = `getAttr ($child[0] + ".ty")`;
			float $componentZ = `getAttr ($child[0] + ".tz")`;
			$length = `mag (>)`; 
		} else {													// If not - set length to 1
			$length = 1;
		}
	int $nGon = `intSliderGrp -q -value "FKnumber"`;				// Read values
	int $height = `intSliderGrp -q -value "FKheight"`;
	float $rad = `floatSliderGrp -q -value "FKradius"`;
	string $orient = `radioCollection -q -sl addFKRadioGrp1`;
	addFKControl( $nGon, $height, $length, $rad, $a, $orient);		// Make the main function
}
}

global proc string addFKControl ( int $nGon, int $height, float $len , float $radius, string $targetName, string $orient) {

string $name = $targetName + "_FK_control";

float $vertCoords[] = {};
string $command = "curve -d 1 ";
float $step = 360/$nGon;
float $angle = 0 - ($step/2);
string $endcommand = " ";
	for ($a = 0; $a 			$angle +=$step;
		float $resultX = (`cos (deg_to_rad($angle))`) * $radius;
		float $resultY = (`sin (deg_to_rad($angle))`) * $radius;
		$vertCoords[($a*2)] = $resultX;
		$vertCoords[($a*2) + 1] = $resultY;
	}

$vertCoords[$nGon*2] = $vertCoords[0];	
$vertCoords[($nGon*2)+1] = $vertCoords[1];	
for ($n = 0; $n 		float $div = 1.0;
	float $flHeight = ($height/$len) * 1.0;
	int $count = 0;
	for ($a = 0; $a 			float $div = `floor($n/$nGon)`;
		$command += "-p " + $vertCoords[($a*2)] + " " + ($n/$flHeight) + " " + $vertCoords[($a*2) + 1] + " ";
		$command += "-p " + $vertCoords[(($a+1)*2)] + " " + ($n/$flHeight) + " " + $vertCoords[(($a+1)*2) + 1] + " ";
		$command += "-p " + $vertCoords[(($a+1)*2)] + " " + (($n+1)/$flHeight) + " " + $vertCoords[(($a+1)*2) + 1] + " ";
		$command += "-p " + $vertCoords[($a*2)] + " " + (($n+1)/$flHeight) + " " + $vertCoords[($a*2) + 1] + " ";
		$command += "-p " + $vertCoords[($a*2)] + " " + ($n/$flHeight) + " " + $vertCoords[($a*2) + 1] + " ";
		$count = $a;
	}
	$command += "-p " + $vertCoords[($count*2)] + " " + (($n + 1)/$flHeight) + " " + $vertCoords[($count*2) + 1] + " ";

}
$command += $endcommand;
$command += " -n ";
$command += $name;
$curveNode = `eval ($command)`;

$curveNodeShape = `listRelatives -c $curveNode`;
rename $curveNodeShape ($curveNode + "Shape");

if ($orient == "posX"){
	setAttr ($curveNode + ".rotateZ") -90;
	makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 $curveNode;
}
if ($orient == "negX"){
	setAttr ($curveNode + ".rotateZ") 90;
	makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 $curveNode;
}
if ($orient == "negY"){
	setAttr ($curveNode + ".rotateZ") 180;
	makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 $curveNode;
}

if ($orient == "posZ"){
	setAttr ($curveNode + ".rotateX") 90;
	makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 $curveNode;
}
if ($orient == "negZ"){
	setAttr ($curveNode + ".rotateZ") -90;
	makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 $curveNode;
}

$controlOrient = `group -em -n ($targetName + "_FK_control_orient")`;
	setAttr ($controlOrient + ".scalePivotX") ($radius / 10);
	setAttr ($controlOrient + ".scalePivotY") ($radius / 10);
	setAttr ($controlOrient + ".scalePivotZ") ($radius / 10);
parent $curveNode $controlOrient;
copyMatrixAddFK ($targetName, $controlOrient, 1);

// Set proper rotation order.

setAttr ($curveNode + ".rotateOrder") (`getAttr ($targetName + ".rotateOrder")`);

return $curveNode;
}

global proc copyMatrixAddFK( string $sourceObj, string $targetObj, int $worldSpace){
string $command;
float $sourceMatrix[];
if($worldSpace == 1){
	$sourceMatrix = `xform -q -ws -m $sourceObj`;
	$command = "xform -ws -m ";
} else {
	$sourceMatrix = `xform -q -os -m $sourceObj`;
	$command = "xform -os -m ";
}

string $matrix;
string $a;
for($a in $sourceMatrix){
	$matrix += $a;
	$matrix += " ";
}

$command += $matrix;
$command += $targetObj;

eval($command);
};

 

Wszystko pięknie bangla. Istny miodek. Big Thx Kroopson za skrypt.

Odnośnik do komentarza
Udostępnij na innych stronach

No tak - ja to pisałem jeszcze w Maya 7 chyba albo w 2008 czyli jakąś epokę temu. Generalnie jak teraz widzę ten faszystowski kod MEL'a to mnie słabi. Autodesk powinien pomyśleć trochu nad API pythona w majce bo nawet Blender wyprzedza ją pod tym względem o lata świetlne.

 

Np. dziś potrzebowałem skryptu który w stabilny, przewidywalny sposób exportował by dane kamery z XSI do After Effects z zachowaniem pixel aspektu. Jako że nie lubię rozwiązań których nie rozumiem wziąłem sobie skrypt który niedawno powstał do Blendera. Zaadaptowanie go do XSI zajęło jakieś 3h. Z majką już by tak super nie było ponieważ nie ma ona domyślnie w pythonie żadnych operacji macierzowych (natywnych dla maya), i ogólnie sam python nie potrafi dostać się do danych obiektu inaczej niż przez zwrapowanego w nim Mel'a (no chyba że coś się ostatnio w tej materii zmieniło)

Edytowane przez Kroopson
Odnośnik do komentarza
Udostępnij na innych stronach

z tego co wiem nic się nie zmieniło. Jakiś czas temu podjąłem się próby pisania w pythonie pod mayą i zrezygnowałem po tym jak się okazało że i tak i tak sprowadza się to do operowania na MELu. A - tak jak mówisz - przydałoby się móc pisać w innym języku niż MEL. Wręcz możnaby się pokusić o aplikację typu Eclipse albo NetBeans dla Mayi. To by dopiero było. Wygodniejsze skryptowanie i tworzenie GUI. Ehh...

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się



×
×
  • Dodaj nową pozycję...

Powiadomienie o plikach cookie

Wykorzystujemy cookies. Przeczytaj więcej Polityka prywatności