Coordinates of the tip of the bone
Posted: Thu Mar 17, 2016 6:13 pm
Any ideas how to calculate the coordinates of the tip of the bone? I'm really bad at vectors...
Ah, of course! Sorry for this newbie question, but where can I access the built-in scripts on mac? I tried in ~/Library folders and Documents/Anime Studio Pro/ -> but couldn't find them... and thank you so much for your help...! Much appreciated!synthsin75 wrote:The AS11 add bone tool snaps to the tip of a nearby bone, so you might look there.
Got it! Thanks!synthsin75 wrote:I don't use Mac, but I seem to remember reading something about right-clicking the program and selecting show package or something.
Code: Select all
local i
local vec = LM.Vector2:new_local()
local tip = LM.Vector2:new_local()
local angle, scale
local bone, boneId
local parent
local pAngle
boneId = moho:Skeleton():BoneID(bone)
vec:Set(bone.fPos)
angle = bone.fAngle
length = bone.fLength
scale = bone.fScale
parent = bone.fParent
pAngle = 0
while parent >= 0 do
local l = moho:Skeleton():Bone(parent).fAngle
pAngle = pAngle + moho:Skeleton():Bone(parent).fAngle
parent = moho:Skeleton():Bone(parent).fParent
end
local cum
i, cum = math.modf ((pAngle + angle)/(2*math.pi))
cum = cum*2*math.pi
tip.x = scale * length * math.cos(cum) + vec.x
tip.y = scale * length * math.sin(cum) + vec.y
Whoa, thank you so much!!! I'm trying to use the coordinates of the bone to move the same Bone layer accordingly in opposite direction so that the bone tip appears to stay still, but the coordinates don't seem to match precisely. The movement is in the right direction, but doesn't align perfectly.hayasidist wrote:Try this...
this will give "world" coordinates of the tip in the same transform space as the bone -- IOW the vector layer in which the coordinates will be at the tip needs to be a child of the bone layer.Code: Select all
local i local vec = LM.Vector2:new_local() local tip = LM.Vector2:new_local() local angle, scale local bone, boneId local parent local pAngle boneId = moho:Skeleton():BoneID(bone) vec:Set(bone.fPos) angle = bone.fAngle length = bone.fLength scale = bone.fScale parent = bone.fParent pAngle = 0 while parent >= 0 do local l = moho:Skeleton():Bone(parent).fAngle pAngle = pAngle + moho:Skeleton():Bone(parent).fAngle parent = moho:Skeleton():Bone(parent).fParent end local cum i, cum = math.modf ((pAngle + angle)/(2*math.pi)) cum = cum*2*math.pi tip.x = scale * length * math.cos(cum) + vec.x tip.y = scale * length * math.sin(cum) + vec.y
By using your code and mixing it with another example I found, I'm now so far that I can calculate bone base position. I'm starting with base and get tip position later when everything works. I go through the bone chain recursively using your idea and then apply the transformation of each bone to the current bone. This works as long as the layer and its parent layers don't have any transformations. So I still need to transform the current layer somehow to compensate for any transformations that are being applied to it, to make the math with the bones work.hayasidist wrote:Try this...
...
this will give "world" coordinates of the tip in the same transform space as the bone -- IOW the vector layer in which the coordinates will be at the tip needs to be a child of the bone layer.
Code: Select all
function JL_compensate_bone_movement:CalculateBonePosition(moho, bone)
local skel
skel = moho:Skeleton()
if (skel == nil) then return end
local i
local vec = LM.Vector2:new_local()
local boneId
local parent
boneId = moho:Skeleton():BoneID(bone)
local curFrame = moho.layer:CurFrame()
-- local m= LM.Matrix:new_local()
-- moho.layer:GetLayerTransform(curFrame,m,moho.document)
vec:Set(bone.fPos)
parent = bone.fParent
while parent >= 0 do
skel:Bone(parent).fMovedMatrix:Transform(vec)
parent = moho:Skeleton():Bone(parent).fParent
end
-- m:Transform(vec)
return vec
end
Yea you did warn me.hayasidist wrote:this is why I said what I said about frames of reference.
where in the hierarchy is the layer in which you want to use the calculated coordinates?
e.g.
Bone <-- calculate here
>vector
Group
>vector <-- use here?
fPos as stored is not changed when the layer / camera transforms change
but the place on the screen where you'll find fPos does change
so if you have different transforms in the Bone and Group layers in the above example then the same fPos in the two vector layers will be in different places on the screen
Maybe this can also give hints about the transform (that I don't understand).The way to move the parent without moving the children would be to transform the children's position into world coordinates (using the inverse of the parent's fRestMatrix), move the parent, and then transform the children bones from world coordinates back to the parent's coordinates using the new fRestMatrix.
A bone's position is always relative to its parent bone (or layer if unparented). So moving/rotating a parent bone will not change the position of its child. A bone's parent is the 0,0 of its coordinate system and those coordinates move with the parent, which moves the child. But the child bone doesn't move in the parent bone coordinates unless you directly move that child.lehtiniemi wrote:Regarding to fPos, it doesn't seem to change when the parent bone is moving the bone, either. This is really weird to me. It only changes when the bone is translated directly but not when the parent is moving it as a part of the skeleton. This makes sense in that the skeleton calculates everything based on bone automations, but it seems to make reading and calculating the bone position unnecessary complicated. Same with fAnimPos.
ok so you want to translate the bone layer? (and not move the camera?) and it's all in just the x/y plane?lehtiniemi wrote: I'm trying to use the coordinates of the bone to move the same Bone layer accordingly in opposite direction so that the bone tip appears to stay still
This is correct. Well, it would be a plus if the script worked even if the camera is animated with pan/zoom. But for starters, we can say that moving camera doesn't need to work. I can always move the camera after the script has been used. And it's all x/y, yes.hayasidist wrote:ok so you want to translate the bone layer? (and not move the camera?) and it's all in just the x/y plane?lehtiniemi wrote: I'm trying to use the coordinates of the bone to move the same Bone layer accordingly in opposite direction so that the bone tip appears to stay still
I wrote this into my code - now the script goes through the transformations and writes the changes into an array. It then goes through the array again, this time applying the transformations from the precalculated values.hayasidist wrote: a couple of initial observations:
> the layer transform matrix will change because you'll be translating the layer. Seems at first sight to be a bit of a catch-22 - you need the transform to get a "screen" position; but you use that to move the layer and so that'll change the transform matrix... hmmm...
> the bone will (likely) move in an arc and the layer will move in a straight line, so the toe will start and end in the right place but won't be right part way through its movement-- so this will need layer keys more frequently than bone keys.
Code: Select all
m:Invert()
moho.document:GetCameraMatrix(moho.frame, cam)
m:Multiply(cam)
m:Invert()