Copy link to clipboard
Copied
In trying to rig this girl character I've had a strange behaviour come up. I could work around it easily enough but it's getting to me that there's something I'm not understanding. My level of experience with expressions is relatively low but I have some Javascript experience so the main principles are clear.
What's annoying me is that my procedure works fine in a simple scene created wholly in AE. However when I import a .psd file (using composition-retain layer sizes), the same approach becomes useless. I feel like I'm missing something about layer sizes in relation to comps or something, or come upon a bug.
Ok this is my first post and its a little involved. I've always been able to find answers by searching online or in documentation. Here goes.
I'm trying to set up a character using Puppet Pins, which I will link to nulls as part of a more complicated setup down the road. My general approach is to set up the pins first and see how it all moves manually before creating nulls and linking the pins to the positions of the nulls. So far so simple. To get my nulls to the exact position of my pins, i pickwhip the null position to the pin position, see what the coords are, then remove the expression and put in the coords manually on the null. Once the nulls and pins are lined up, I just link the pins to the nulls with an expression in the pins "position" property.
This all works fine in my simple scene consisting of a solid layer with puppet pins applied, and some nulls. The nulls snap to the pins perfectly, and I don't have to convert the pin coordinates to comp space or anything. The pins coords seem to be in comp space already. Then I can link the pins to my nulls and all is fine.
However, in my complex scene which is generated from an imported .psd, the pin coords do not correspond to comp space. They're very low and seem to match up to the layer the puppet effect was applied to. So the null ends up way off near the top left of the comp.
No problem. We just run toComp on the position of the pin and we should get the comp space coords of the pin. But I don't. I get something way off.
Why do the pin positions not map to comp space automatically in my psd-based comp, as they did with the simple comp?
Is it even possible to run toComp successfully in the following way
toComp(thisComp.layer("R_Arm").effect("Puppet").arap.mesh("Mesh 1").deform("Puppet Pin 1").position);
or is the return of
thisComp.layer("R_Arm").effect("Puppet").arap.mesh("Mesh 1").deform("Puppet Pin 1").position;
not of the right data type to be an argument of toComp?
Are pin coordinates just layer based coordinates like any other or are there other factors involved?
I'd like to be able to set up pins where I want them and link them to nulls with exactly matching coordinates so the artwork doesn't jump when I link them.
More generally, is there any attribute of a psd file that can affect the coordinate system of a comp generated on import. The file in question contained all regular layers, plus one group of 3 (which came in as a pre-comp the entire size of the main comp, as expected), no layer effects or anything else fishy.
Anyone more experienced with expressions and coordinate spaces in AE have any idea what I'm missing?
Macbook Pro Early 2011 15" i7 2.2Ghz
16gb RAM
AMD Radeon 6750 1GB
OSX 10.9.2
AE 12.2.1.5
I think that would be something like this:
L = thisComp.layer("Blue Solid 1");
L.toComp(L.effect("Puppet").arap.mesh("Mesh 1").deform("Puppet Pin 1").position)
Dan
Copy link to clipboard
Copied
Well, first off: Since you claim to have experience in JS, then why the heck don't you simplify your setup by declaring your own variables? This is a bloody eyesore and would be a complete nightmare to deal with when adding further code. That said, .toComp() is still a method, so you need to tell it on which data to operate:
myPin.toComp(myPin.position)
That's probably the point of failure in your setup. It only accidentally works in your otehr scenario since when the mesh fits within the comp bounds, the coordinates will always be identical to begin with (if you don't move the layer, that is).
Mylenium
Copy link to clipboard
Copied
Hi Mylenium,
Sorry for my lack of variables.
I tried it again with a variable for the pin (myPin1) and tried calling .toComp in the following manner:
myPin1 = thisComp.layer("R_Leg").effect("Puppet").arap.mesh("Mesh 1").deform("Puppet Pin 1");
myPin1.toComp(myPin1.position);
This throws up an error, "function 'myPin1.toComp' is not defined", so I presume that the value that is returned to variable myPin1 doesn't have a method ".toComp".
If I remove the myPin and just pass the position property of myPin1 to toComp as a function,
myPin1 = thisComp.layer("R_Leg").effect("Puppet").arap.mesh("Mesh 1").deform("Puppet Pin 1");
toComp(myPin1.position);
it doesn't error, it returns some coordinates, but not the right ones.
Just as a test, I made a second null layer and did this in its position expression:
myNull = thisComp.layer("Null 20");
myNullpos = myNull.toComp(myNull.anchorPoint);
The second null mapped perfectly to the first with identical coords.
Same result for this:
myNull = thisComp.layer("Null 20");
myNullpos = myNull.position;
Try:
myNull = thisComp.layer("Null 20");
myNullpos = myNull.anchorPoint;
And I get 0,0 , presumably because the anchorPoint coords are layer coords. The anchorpoint of a null is at 0,0 on the layer by default.
Now if I try one more permutation calling myNull.toComp on the myNull.position property (a composition space position coordinate):
myNull = thisComp.layer("Null 20");
myNullpos = myNull.toComp(myNull.position);
I get a position way off to the bottom right.
So what I take from all this is:
1- I can use .toComp with my null layer as myNull.toComp() but not with myPin1 as myPin1.toComp(). I presume whatever is returned by the pin query doesn't have a method .toComp, while the null layer returned to variable myNull, does. So maybe its not possible to get comp space coordinates of a pin using this approach. Like it only works for layers not sub-layer items like pins.
2- Using myNull.toComp(), I get the right result passing myNull.anchorPoint. I also get the right result if I dispense with .toComp and just use myNull.position, so presuably they're equal. Using just myNull.anchorPoint gives the position of the anchor within the layer (0,0 by default) and using myNull.toComp() and passing myNull.position gives a position to the far bottom right of the correct one (presumably because myNull.position is already a comp space coord, I don't know the internals of .toComp).
So my conclusion thus far is that the pin position coords, when passed to .toComp() dont work, so they must be in some way differently defined than the anchorpoint of a null, which does work. whatever is returned by the pin query has no .toComp method.
The method seems to need an anchorPoint to be passed, and a pin position doesn't seem to serve the same purpose.
So is there a different method to get the comp space coords of a PP or is there some property of a PP which can be passed to .toComp?
Copy link to clipboard
Copied
Thinking about this another way.
What if I define the problem like this:
I've seen lots of expressions that allow you to link a puppet pin to a null so that the puppet pin is child and follows the null.
If I wanted to do the opposite, make a null ( or other item) follow an individual puppet pin, how would I go about it? Presumably by putting an expression in the position property of the null which evaluates to the position of the pin on screen. But I can't figure what that expression would be.
Suggestions?
Copy link to clipboard
Copied
I think that would be something like this:
L = thisComp.layer("Blue Solid 1");
L.toComp(L.effect("Puppet").arap.mesh("Mesh 1").deform("Puppet Pin 1").position)
Dan
Copy link to clipboard
Copied
Hi Dan,
Thanks for your input. Satisfyingly for me () I had already arrived at the solution through thinking about the conclusions I drew from my post 2 above. Mainly that toComp is a method that needs to be called on a layer. I meant to update this with the solution but I figured it out with seconds before a rugby match began on TV and I forgot about it then.
So your answer is correct and right (unsurprisingly, your reputation precedes you). Here's my version anyway for the record.
myPin1 = thisComp.layer("R_Leg").effect("Puppet").arap.mesh("Mesh 1").deform("Puppet Pin 1").position;
legLayer = thisComp.layer("R_Leg");
legLayer.toComp(myPin1);
I just have the extra line at the top declaring a variable for the pin.
Thanks to you and Mylenium.
Mark
Copy link to clipboard
Copied
UPDATE: SOLVED
So thanks to the prompt from Mylenium about toComp being a method and therefore needing to be called on some object, I did the few experiments in post 2. It turned out that toComp wasn't a method of puppet pins so Mylenium's suggestion wasn't quite right. It has to be called on a layer.
So the final answer for me was
myPin1 = thisComp.layer("R_Leg").effect("Puppet").arap.mesh("Mesh 1").deform("Puppet Pin 1").position;
legLayer = thisComp.layer("R_Leg");
legLayer.toComp(myPin1);
Call the method on a layer and pass it the pin position as an argument.
Dan Ebberts supplied me with the same solution while I was away figuring it out for myself.
L = thisComp.layer("Blue Solid 1");
L.toComp(L.effect("Puppet").arap.mesh("Mesh 1").deform("Puppet Pin 1").position)
Thanks to both for making me think in the right direction (Mylenium) and supplying confirmation (for my own mind) that my solution is a good one(Dan).