Добавление вторичного направления управления к родительскому объекту в Maya

Я наткнулся на «скрипт заклепок», когда искал решение для движения змеиной чешуи. Мне нужно удерживать твердый объект (весы) в согласованной точке с деформирующей. Сценарий отлично работает, но теперь в процессе td у меня есть некоторые другие аспекты, которые мне нужно решить. Мне нужно дополнительное направление ограничения помимо вектора нормали вершины, полученного из родительского многоугольника, чтобы указать, как движется дочерний элемент. План состоит в том, чтобы попытаться изменить сценарий так, чтобы вторичное направление следовало за потоком краев к переднему концу объекта. Я надеюсь, что смогу легко взять это векторное направление от самого края, но у меня есть ощущение, что это может быть не так просто. У меня есть некоторый ограниченный опыт создания такого рода отношений на основе ограничений с использованием точечных и перекрестных произведений в houdini, но в Maya это немного сложнее для меня. Я уверен, что мне нужно только еще одно направление. Любые предложения о том, как решить эту проблему? Я прикрепил несколько изображений низкополигонального тестового объекта, чтобы дать вам лучшее представление. На первом показана кривая в состоянии покоя в состоянии покоя, а на двух вторых изображениях показано, как вторичная кривая отклоняется от идеального положения вектора вдоль поверхности тела «змеи».

Вот ссылка на скрипт https://www.creativecrash.com/maya/script/rivet-button/description#tabs

Вместе со ссылкой на эталонное изображение https://drive.google.com/file/d/0B1O6s3CJ1wwlN1lOS1E1ZXVuOVk/view?usp=sharing

А вот и сценарий,

// Copyright (C) 2000-2001 Michael Bazhutkin - Copyright (C) 2000 studio Klassika
// www.geocites.com/bazhutkin
// [email protected]
//
//  Rivet (button) 1.0
//  Script File
//  MODIFY THIS AT YOUR OWN RISK
//
//  Creation Date:  April 13, 2001
//
//
//  Description:
//  Use "Rivet" to constrain locator to polygon or NURBS surfaces
//  Select two edges on polygon object
//  or select one point on NURBS surface and call rivet
//  Parent your rivets and buttons to this locator

global proc string rivet ( )
{

string $nameObject;
string $namePOSI;

string $parts[];
string $list[] = `filterExpand -sm 32`;
int $size = size($list);
if ($size > 0)
{
    if ($size != 2)
    {   error("No two edges selected");
        return "";
    }

    tokenize($list[0],".",$parts);
    $nameObject = $parts[0];
    tokenize($list[0],"[]",$parts);
    float $e1 = $parts[1];
    tokenize($list[1],"[]",$parts);
    float $e2 = $parts[1];

    string $nameCFME1 = `createNode curveFromMeshEdge -n "rivetCurveFromMeshEdge1"`;
        setAttr ".ihi" 1;
        setAttr ".ei[0]"  $e1;
    string $nameCFME2 = `createNode curveFromMeshEdge -n "rivetCurveFromMeshEdge2"`;
        setAttr ".ihi" 1;
        setAttr ".ei[0]"  $e2;
    string $nameLoft = `createNode loft -n "rivetLoft1"`;
        setAttr -s 2 ".ic";
        setAttr ".u" yes;
        setAttr ".rsn" yes;

    $namePOSI = `createNode pointOnSurfaceInfo -n "rivetPointOnSurfaceInfo1"`;
        setAttr ".turnOnPercentage" 1;
        setAttr ".parameterU" 0.5;
        setAttr ".parameterV" 0.5;

    connectAttr -f ($nameLoft + ".os") ($namePOSI + ".is");
    connectAttr ($nameCFME1 + ".oc") ($nameLoft + ".ic[0]");
    connectAttr ($nameCFME2 + ".oc") ($nameLoft + ".ic[1]");
    connectAttr ($nameObject + ".w") ($nameCFME1 + ".im");
    connectAttr ($nameObject + ".w") ($nameCFME2 + ".im");
}
else
{   $list = `filterExpand -sm 41`;
    $size = size($list);

    if ($size > 0)
    {
        if ($size != 1)
        {   error("No one point selected");
            return "";
        }
        tokenize($list[0],".",$parts);
        $nameObject = $parts[0];
        tokenize($list[0],"[]",$parts);
        float $u = $parts[1];
        float $v = $parts[2];
        $namePOSI = `createNode pointOnSurfaceInfo -n "rivetPointOnSurfaceInfo1"`;
                setAttr ".turnOnPercentage" 0;
                setAttr ".parameterU" $u;
                setAttr ".parameterV" $v;
        connectAttr -f ($nameObject + ".ws") ($namePOSI + ".is");
    }
    else
    {   error("No edges or point selected");
        return "";
    }
}

string $nameLocator = `createNode transform -n "rivet1"`;
createNode locator -n ($nameLocator + "Shape") -p $nameLocator;

string $nameAC = `createNode aimConstraint -p $nameLocator -n ($nameLocator + "_rivetAimConstraint1")`;
    setAttr ".tg[0].tw" 1;
    setAttr ".a" -type "double3" 0 1 0;
    setAttr ".u" -type "double3" 0 0 1;
    setAttr -k off ".v";
    setAttr -k off ".tx";
    setAttr -k off ".ty";
    setAttr -k off ".tz";
    setAttr -k off ".rx";
    setAttr -k off ".ry";
    setAttr -k off ".rz";
    setAttr -k off ".sx";
    setAttr -k off ".sy";
    setAttr -k off ".sz";

connectAttr ($namePOSI + ".position") ($nameLocator + ".translate");
connectAttr ($namePOSI + ".n") ($nameAC + ".tg[0].tt");
connectAttr ($namePOSI + ".tv") ($nameAC + ".wu");
connectAttr ($nameAC + ".crx") ($nameLocator + ".rx");
connectAttr ($nameAC + ".cry") ($nameLocator + ".ry");
connectAttr ($nameAC + ".crz") ($nameLocator + ".rz");

select -r $nameLocator;
return ($nameLocator);

}

rivet; 

person JKeil    schedule 26.04.2016    source источник
comment
Спасибо за предложение. Изучаю x gen сейчас. Я обязательно опубликую, если смогу решить проблему в течение следующего дня или двух, используя его.   -  person JKeil    schedule 27.04.2016


Ответы (1)


Вместо использования сценария заклепки используйте встроенные волосяные фолликулы. Они несут с собой всю информацию о нормали и касательной, поэтому их можно анимировать с помощью значений UV, и они предоставляют узел для группировки ваших ограниченных объектов.

Вы можете добавить фолликулы с помощью команд меню, рисуя их на поверхностях и используя код:

createNode "follicle"
// follicleShape1 // (u should capture and use this name, im being lazy below)
connectAttr ($targetMeshShape+".outMesh") "follicleShape1.inputMesh";
connectAttr ($targetMeshShape+".worldMatrix") "follicleShape1.inputWorldMatrix";
connectAttr "follicleShape1.outTranslate" "follicle1.translate";
connectAttr "follicleShape1.outRotate" "follicle1.rotate";

//UV attributes control placement on surface 
setAttr "follicleShape1.parameterU" $goToU;
setAttr "follicleShape1.parameterV" $goToV;

Но в этом отношении похоже, что сценарий заклепки также использует значения UV для позиционирования точек. Таким образом, с хорошо ориентированными значениями UV* на базовом меше должно быть легко перемещать заклепки или фолликулы по поверхности, просто анимируя их значения UV.

* Это означает отсутствие перекрывающихся UV, все вершины в пределах диапазона [0.0,1.0] и с осями UV, указывающими в направлении потока и перпендикулярными ему соответственно.

person rebusB    schedule 01.06.2016