JKeil
JKeil

Reputation: 11

Adding Secondary Control Direction to Parented object in Maya

I stumbled on the 'rivet script' when I was looking for a solution to movement for snake scales. I need to constain a rigid object (the scales) at a consistent point to a deforming one. The script has been working great, but now further into the td process I have some other aspects that I need to resolve. I need an additional constraint direction besides the vertex normal vector obtained from the parent polygon to dictate how the child moves. The plan is to try and modify the script so that the secondary direction follows the edge flow towards the front end of the object. I am hoping I can take this vector direction easily from the edge itself, but I have a feeling it might not be that simple. I have some limited experience doing this sort of constraint based relationship using dot products and cross products in houdini, but in Maya its a bit more challenging for me. I am confident that I do only need one more direction though. Any suggestions on how to resolve this? I have attached several images on a low poly test object to give you a better idea. The first shows the curve at rest in rest position, while the two second images show how the secondary curve deviates from the ideal vector position along the 'snakes' body surface.

Here is the link to the script https://www.creativecrash.com/maya/script/rivet-button/description#tabs

Along with a link to the reference picture https://drive.google.com/file/d/0B1O6s3CJ1wwlN1lOS1E1ZXVuOVk/view?usp=sharing

And here is the script,

// 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; 

Upvotes: 0

Views: 611

Answers (1)

rebusB
rebusB

Reputation: 517

Instead of using the rivet script use the built in hair follicles. They carry with them all the normal and tangent information thus can be animated via UV values and they provide a node for grouping your constrained objects under.

You can add the follicles via menu commands, by painting them on surfaces and via code:

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;

But for that matter it looks like the rivet script also uses UV values for positioning points. So with well oriented UV values* on your base mesh it should be easy to move either the rivets or follicles along the surface by simply animating their UV values.

*That means no overlapping UV's, all vertices within the range [0.0,1.0] and with the UV axes pointing in and perpendicular to the direction of flow respectively.

Upvotes: 1

Related Questions