Page 1 of 1
Getting position for bone that's moved by other bones
Posted: Thu Mar 17, 2016 6:56 pm
by lehtiniemi
How can I get coordinates for a bone that's not animated but is moved by other bones?
fAnimPos doesn't seem to return anything. I tried to use bone.fAnimPos:GetValue(frameNumber) to get coordinates for a bone that's not animated by itself but is moved by the rest of the skeleton. It returns no movement. Then I figured that maybe fPos contains the absolute position even though it's not animated, but bone.fPos:GetValue(frameNumber) returns an error - there doesn't seem to be get-function for this.
Any ideas on how to get access to this position data?
Re: Getting position for bone that's moved by other bones
Posted: Thu Mar 17, 2016 7:04 pm
by synthsin75
Off the top of my head... bone.fPos and bone.fPos.x for specific axis.
Re: Getting position for bone that's moved by other bones
Posted: Thu Mar 17, 2016 7:06 pm
by lehtiniemi
synthsin75 wrote:Off the top of my head... bone.fPos.value and bone.fPos.value.x for specific axis.
Hmm, but how can I specify the frame where I want the bone position at? fAnimPos:GetValue(frameNumber) returns the bone position at the specified frame number, but for some reason it doesn't return the bone position when it's animated by other bones.
Can I somehow get fPos at a specified frame? Or is this the bone position at frame 0?
Re: Getting position for bone that's moved by other bones
Posted: Thu Mar 17, 2016 8:03 pm
by lehtiniemi
Here's modified code that I found on the forum. It should do something like what I'm trying to achieve: when you give it bone and atFrame, it should calculate the position of the bone at that frame. But bone base coordinates (vec1) doesn't seem to return anything and bone tip (vec2) coordinates are "stuttering" somehow and don't correspond tip position exactly.
Any idea what could the problem?
Code: Select all
function JL_compensate_bone_movement:CalculateBonePosition(moho, bone, atFrame)
local skel
if (moho.layer:LayerType() == MOHO.LT_BONE) then
skel= moho:Skeleton()
else
skel= moho:ParentSkeleton()
end
if (skel == nil) then return end
local vec1= LM.Vector2:new_local()
local vec2= LM.Vector2:new_local()
local pt1= LM.Point:new_local()
local pt2= LM.Point:new_local()
local m= LM.Matrix:new_local()
moho.layer:GetFullTransform(atFrame,m,moho.document)
--root
if (atFrame == 0) then
vec1:Set(bone.fAnimPos:GetValue(0))
if (bone.fParent >= 0) then
skel:Bone(bone.fParent).fRestMatrix:Transform(vec1)
end
else
vec1:Set(bone.fPos)
if (bone.fParent >= 0) then
skel:Bone(bone.fParent).fMovedMatrix:Transform(vec1)
end
end
m:Transform(vec1)
--tip
vec2:Set(bone.fLength,0)
vec2:Rotate(bone.fAnimAngle:GetValue(atFrame))
if (atFrame == 0) then
vec2= vec2 + bone.fAnimPos:GetValue(0)
if (bone.fParent >= 0) then
skel:Bone(bone.fParent).fRestMatrix:Transform(vec2)
end
else
vec2= vec2 + bone.fPos
if (bone.fParent >= 0) then
skel:Bone(bone.fParent).fMovedMatrix:Transform(vec2)
end
end
m:Transform(vec2)
return vec2
end
Re: Getting position for bone that's moved by other bones
Posted: Thu Mar 17, 2016 9:00 pm
by synthsin75
Temporarily select the frame, get the .fPos, and select the original frame again.
Re: Getting position for bone that's moved by other bones
Posted: Fri Mar 18, 2016 4:11 am
by lehtiniemi
synthsin75 wrote:
Temporarily select the frame, get the .fPos, and select the original frame again.
Thanks for the idea! I tried this, but this doesn't return the absolute position of the bone either. It also only returns values if the bone is animated with keyframes:
Code: Select all
for i = newStartFrame, newEndFrame do
moho:SetCurFrame(i)
bonePosition = skel:Bone(skel:SelectedBoneID()).fPos
print(bonePosition.x)
end
This returns no movement when the bone is moved by the skeleton.
What else could I try...?
Re: Getting position for bone that's moved by other bones
Posted: Fri Mar 18, 2016 9:44 am
by synthsin75
lehtiniemi wrote:Thanks for the idea! I tried this, but this doesn't return the absolute position of the bone either. It also only returns values if the bone is animated with keyframes:
Code: Select all
for i = newStartFrame, newEndFrame do
moho:SetCurFrame(i)
bonePosition = skel:Bone(skel:SelectedBoneID()).fPos
print(bonePosition.x)
end
This returns no movement when the bone is moved by the skeleton.
What else could I try...?
An unanimated bone will never show a different position than frame zero. See my response in your other thread.
Re: Getting position for bone that's moved by other bones
Posted: Sun Mar 20, 2016 12:50 pm
by lehtiniemi
Anyone who looks for answer to this, here's how you do it. This function returns the position of the bone in the current layer coordinates. If you want global coordinates, there's a change in the Transform-sentence at the end, just switch from GetLayerTransform to GetFullTransform and add moho.document as last argument to take camera transformation into account.
Code: Select all
-- Calculates bone position and returns the coordinates within the current layer space
function CalculateBonePosition(moho, bone, frame)
local skel
skel = moho:Skeleton()
if (skel == nil) then return end
local i
local vec = LM.Vector2:new_local()
local boneId
local parent
-- Save current frame before jumping to frame given as argument
-- This is because fPos is the bone position at current keyframe so you have to jump there to get it
local curFrame = moho.layer:CurFrame()
if not (frame == curFrame) then
moho:SetCurFrame(frame)
end
boneId = moho:Skeleton():BoneID(bone)
vec:Set(bone.fPos)
parent = bone.fParent
-- Apply parent transformation to the current bone. This seems to include all the transformations caused by the following parents so
-- you only need to read it from the first parent.
if (parent >= 0) then skel:Bone(parent).fMovedMatrix:Transform(vec) end
-- Lastly, apply transformations by the current layer and its parents
local m= LM.Matrix:new_local()
moho.layer:GetLayerTransform(frame,m, nil) -- bypass camera transformations by passing nil as document object
-- As a sidenote, if you want to take parent and camera transformations into account, you should use this instead:
-- moho.layer:GetFullTransform(frame,m, moho.document)
m:Transform(vec)
-- Move back to original frame before jumping
if not (frame == curFrame) then
moho:SetCurFrame(curFrame)
end
return vec
end