CONTROL BONES FROM PARENT LAYER (FINISHED)

Moho allows users to write new tools and plugins. Discuss scripting ideas and problems here.

Moderators: Víctor Paredes, Belgarath, slowtiger

dkwroot
Posts: 677
Joined: Thu May 02, 2013 6:56 am
Location: USA
Contact:

CONTROL BONES FROM PARENT LAYER (FINISHED)

Post by dkwroot »

UPDATED:



Basic Info: This script allows you to control bones within child bone or switch layers. In other words, if you have a situation that looks like this:

Bone Layer A:
---Bone Layer B: (Has a bone called "hands")
--------Vector Layer (Named Hands)

You can control the bone "hands" in Bone Layer B from Bone Layer A. Just embed my script in Bone Layer B and then create a new bone in Bone Layer A and name it the same as the bone you want to control in the lower bone layer. If you're confused, here's an example:

Bone Layer A: (Now has a new bone called "hands")
--Bone Layer B: (Has a bone called "hands" and this layer has the control script attached to it)
---------Vector Layer (Named Hands)

This script works for smartbones and it's independent of grid location so you can put bones where ever the heck you want!

This script comes in 2 flavors! The first is Global and the other is Switch Sensitive.
The global version of the script controls everything you assign beneath it. This will work for most occasions, but it might get a little troublesome if you have a switch layer with a bunch of bones. This script could crash your program if you try to control something like 20 smart bones in a switch layer all at the same time, so I created a switch sensitive version as well.

The Switch Sensitive version of this script only moves the bones in a switch layer that is currently active, essentially ignoring all the inactive bones. :D

DOWNLOAD LINK: https://docs.google.com/file/d/0Bwzk-fA ... sp=sharing
GLOBAL VERSION:

Code: Select all

-- #####################################################
-- NESTED BONE CONTROL - Layer Script
-- v1.0
-- Created by Derek Root
-- DKWROOT @ Lost Marble Forums
-- #####################################################

function LayerScript(moho)

   local skel = moho:Skeleton()
   local parent_skeleton=moho:ParentSkeleton()
   local frame = moho.frame
   
   
   if (skel == nil) then
      return
   end
   
   if (parent_skeleton == nil) then
      return
   end
   
   for i=0, skel:CountBones()-1 do
      local child_bone=skel:Bone(i)

      for j=0, parent_skeleton:CountBones()-1 do
         local parent_bone=parent_skeleton:Bone(j)

         if (child_bone:Name() == parent_bone:Name()) then
            
            child_bone.fStrength = parent_bone.fStrength
            child_bone.fLength = parent_bone.fLength
            child_bone.fOffset = parent_bone.fOffset
			child_bone.fAngle = parent_bone.fAngle
			child_bone.fScale = parent_bone.fScale
			
            if (frame>0) then
			
				local origin = LM.Vector2:new_local()
				local bonemoved = LM.Vector2:new_local()
				local origin2 = LM.Vector2:new_local()
			
				origin:Set(0,0)
				parent_bone.fRestMatrix:Transform(origin)
				
				bonemoved:Set(0,0)
				parent_bone.fMovedMatrix:Transform(bonemoved)
				
				local dxy = origin - bonemoved
				
				if (child_bone.fParent < 0 ) then
					origin2:Set(0,0)
					child_bone.fRestMatrix:Transform(origin2)
					child_bone.fPos.x = origin2.x - dxy.x
					child_bone.fPos.y = origin2.y - dxy.y
					
				else
					--THIS PART WOULD ALLOW CONTROL BONES TO MOVE NESTED BONES THAT ARE LINKED
					--UNFORTUNATELY, I HAVE YET TO MAKE IT WORK.
					
				end
            end
        end
	
	end
   
   skel:UpdateBoneMatrix()
end
end
DOWNLOAD: DOWN FOR FIXING
SWITCH SENSITIVE VERSION:

Code: Select all

-- #####################################################
-- NESTED BONE CONTROL - Layer Script
-- v1.0
-- Created by Derek Root
-- DKWROOT @ Lost Marble Forums
-- #####################################################

function LayerScript(moho)

   local skel = moho:Skeleton()
   local parent_skeleton=moho:ParentSkeleton()
   local frame = moho.frame
   
   
   if (skel == nil) then
      return
   end
   
   if (parent_skeleton == nil) then
      return
   end
   
   local parLayer = moho.layer:Parent()
   local TEST = 0
   
   if (parLayer:LayerType() == 5) then
		local switchname = parLayer:SwitchValues():GetValue(frame)
		if (moho.layer:Name() == switchname) then
			TEST = 1
		else
			TEST = 0
		end
	else
		TEST = 1
	end

	if (TEST == 1) then
		for i=0, skel:CountBones()-1 do
			local child_bone=skel:Bone(i)

			for j=0, parent_skeleton:CountBones()-1 do
				local parent_bone=parent_skeleton:Bone(j)

				if (child_bone:Name() == parent_bone:Name()) then
            
					child_bone.fAngle = parent_bone.fAngle
					child_bone.fScale = parent_bone.fScale
					child_bone.fStrength = parent_bone.fStrength
					child_bone.fLength = parent_bone.fLength
					child_bone.fOffset = parent_bone.fOffset
					
					
					if (frame>0) then
					
						local origin = LM.Vector2:new_local()
						local bonemoved = LM.Vector2:new_local()
						local origin2 = LM.Vector2:new_local()
					
						origin:Set(0,0)
						parent_bone.fRestMatrix:Transform(origin)
						
						bonemoved:Set(0,0)
						parent_bone.fMovedMatrix:Transform(bonemoved)
						
						local dxy = origin - bonemoved
						
						if (child_bone.fParent < 0 ) then
							origin2:Set(0,0)
							child_bone.fRestMatrix:Transform(origin2)
							child_bone.fPos.x = origin2.x - dxy.x
							child_bone.fPos.y = origin2.y - dxy.y
					
						end
					end
				end
			end
   
   skel:UpdateBoneMatrix()
		end
	end
end
Last edited by dkwroot on Mon Jul 29, 2013 12:49 am, edited 5 times in total.
Breinmeester
Posts: 303
Joined: Thu May 13, 2010 2:01 pm

Re: A BONE CONTROL SCRIPT (NEEDS WORK!)

Post by Breinmeester »

I haven't got time to fully dive into what youre trying to accomplish, so this might be a stupid suggestion, but can't you use the fMovedMatrix of the bones or the GetFullTransform matrix to compensate for the layer or bone transformations of the child layer?
dkwroot
Posts: 677
Joined: Thu May 02, 2013 6:56 am
Location: USA
Contact:

Re: A BONE CONTROL SCRIPT (NEEDS WORK!)

Post by dkwroot »

Breinmeester wrote:I haven't got time to fully dive into what youre trying to accomplish, so this might be a stupid suggestion, but can't you use the fMovedMatrix of the bones or the GetFullTransform matrix to compensate for the layer or bone transformations of the child layer?

No, it's not a stupid suggestion at all! I actually didn't know about those features and I've been working like crazy over the past few days to figure them out. Anyway, I got the script up and running! Everything works on it perfectly, except for one issue.

When dealing with bones that are parented to other bones (chain of bones), the script causes the angles and movements of the bones to move wrong. I've been pondering this for the last day or so and I think I have a solution but need some information.

Does anyone know how the fIKGlobalAngle function work? I believe it's a function that allows someone to access the angle of a bone at a specified frame, but I'm not sure how to call it.
User avatar
heyvern
Posts: 7035
Joined: Fri Sep 02, 2005 4:49 am

Re: A BONE CONTROL SCRIPT (NEEDS WORK!)

Post by heyvern »

fIKGlobalAngle has to do with the IK of bones. It's used when using the bone lock feature. I don't think you need to use this for what you are doing. It really has nothing really to do with controlling bones unless you are doing something with IK. I do a ton of bone manipulation with scripting and never worry about this or other IK properties of the bones.
User avatar
heyvern
Posts: 7035
Joined: Fri Sep 02, 2005 4:49 am

Re: A BONE CONTROL SCRIPT (NEEDS WORK!)

Post by heyvern »

I ran your script and it seems to work fine. Can you explain what situation causes the parented/child bones to rotate incorrectly?

I discovered a slight rotation offset of the child bone layer because I didn't release the layer. If a child layer is controlled by bones you are going to see the child bone layer move around.

Another issue is the parent/child bone relationship must be identical in both the child and parent bone layers. If you have a different parent/child relationship of the parent control bones than the child bone layer the rotations will be wrong because the transform matrix is different.
dkwroot
Posts: 677
Joined: Thu May 02, 2013 6:56 am
Location: USA
Contact:

Re: A BONE CONTROL SCRIPT (NEEDS WORK!)

Post by dkwroot »

heyvern wrote:I ran your script and it seems to work fine. Can you explain what situation causes the parented/child bones to rotate incorrectly?

I discovered a slight rotation offset of the child bone layer because I didn't release the layer. If a child layer is controlled by bones you are going to see the child bone layer move around.

Another issue is the parent/child bone relationship must be identical in both the child and parent bone layers. If you have a different parent/child relationship of the parent control bones than the child bone layer the rotations will be wrong because the transform matrix is different.

This is strange, but I can't get my own script to even work for me anymore! When I load up that script, it tells me that pos_temp of line 44 is a null value. I'm not sure what is going on there, it used to work and now it doesn't.

Anyway, I wasn't referring to that old script. I went ahead and updated the script using Breinmeesters suggestion and it's awesome, but I have a rotation issue when it comes to bone parenting.

Code: Select all

function LayerScript(moho)

   local skel = moho:Skeleton()
   local parent_skeleton=moho:ParentSkeleton()
   local frame = moho.frame
   
   
   if (skel == nil) then
      return
   end
   
   if (parent_skeleton == nil) then
      return
   end
   
   for i=0, skel:CountBones()-1 do
      local child_bone=skel:Bone(i)
	  
	  
	    --if (child_bone.fParent >= 0) then
			--local loc_parbone = skel:Bone(child_bone.fParent)
		
			--if (loc_parbone.fSelected) then
				--child_bone.fAngle = loc_parbone.fAngle
			
			
			--end
		--end
	  
	  

      for j=0, parent_skeleton:CountBones()-1 do
         local parent_bone=parent_skeleton:Bone(j)

         if (child_bone:Name() == parent_bone:Name()) then
            
            child_bone.fStrength = parent_bone.fStrength
            child_bone.fLength = parent_bone.fLength
            child_bone.fOffset = parent_bone.fOffset
			child_bone.fAngle = parent_bone.fAngle
			child_bone.fScale = parent_bone.fScale
			
            if (frame>0) then
			
				local origin = LM.Vector2:new_local()
				local bonemoved = LM.Vector2:new_local()
				local origin2 = LM.Vector2:new_local()
			
				origin:Set(0,0)
				parent_bone.fRestMatrix:Transform(origin)
				
				bonemoved:Set(0,0)
				parent_bone.fMovedMatrix:Transform(bonemoved)
				
				local dxy = origin - bonemoved
				
				origin2:Set(0,0)
				child_bone.fRestMatrix:Transform(origin2)
				
				child_bone.fPos.x = origin2.x - dxy.x
				child_bone.fPos.y = origin2.y - dxy.y
				
			break
            end
		break
        end
	
	end
   

   
   skel:UpdateBoneMatrix()
end
end

This script allows you to move nested bones around and rotate from any position. You can scatter the parent bones on upper layers and control the bones of lower layers without having to worry about any bone snapping to a position. It's exactly what I wanted to make, but here's the problem...

Make some nested objects, then put those objects in a bone layer. Then assign each nested object to a bone in the bone layer and make sure the bones have their influence field turned to zero. Then make another bone layer and put the first bone layer into that one. Make more bones in the top bone layer and name them the same names as the bottom bone layer bones. Notice that it doesn't matter where you put the bones in the lop layer, the bones in the lower layers still work.

The problem comes up when you parent the bones of the top bone layer. When you rotate the main parent bone (Make sure you use at least 3 bones in the bone chain to see what I'm talking about) the bones follow the main bone, but don't rotate properly. This causes the bones to go out of alignment. I've tried all kinds of ideas, but nothing works!


If my old script is working for you, I have NO idea how you got it working. Maybe it's running off of another script of yours or something ... I dunno.
User avatar
heyvern
Posts: 7035
Joined: Fri Sep 02, 2005 4:49 am

Re: A BONE CONTROL SCRIPT (NEEDS WORK!)

Post by heyvern »

I basically copied the code from your last post and saved it as a layer script. It worked no problem.

Based on your description, it would seem to me that it's the change in parenting relationship that is causing odd rotation... plus possibly any other object linking to bones. If a bone rotates a layer which is bound to a bone that is also rotating... which is not the same child/parent bone relationship... then no, it isn't going to work as expected.

Haven't tested your latest script yet.
User avatar
heyvern
Posts: 7035
Joined: Fri Sep 02, 2005 4:49 am

Re: A BONE CONTROL SCRIPT (NEEDS WORK!)

Post by heyvern »

Very strange, it would appear I get inconsistent results from the script.

The first time I used it it worked fine. But since then I keep getting errors based on the global tables the script uses. I don't know how the original script you based this on worked but I think your use of _G global tables is over complicating it.

Generally I just use "generic" local table variables that are associated with the layer itself. Just a single table with all of the bones and bone information and then just access the keys of the table using the bone ID. As long as the local variable is declared within the layerscript function the script can access it.

Code: Select all

function LayerScript(moho)
   -- variables declared here
   -- 
   -- 
   local bonetable = {}
In this case the table "bonetable" is accessible anywhere in the LayerScript() function. I've never used _G or even seen it in any scripts to be honest. I am not saying it wouldn't work but I just don't think it's needed and don't know how it would effect Anime Studio.

I am not sure about your table creation and indexing. It doesn't look correct at first glance but I would have to fiddle around with what you are trying to do to be sure.

Keep in mind that lua tables are 0 based. To access arrays and tables that aren't indexed they start with 0 not 1. This applies to everything in Anime Studio, bones, points etc. The index always starts at 0.

Don't use the bone name as the index since bones can have the same name and this will cause all kinds of issues, you need a unique index for the bones in the table. Bone IDs are ALWAYS unique. AS creates internal unique IDs for the bones. These are perfect for indexing tables in lua for scripting.

Code: Select all

   for i=0, skel:CountBones()-1 do
      local mybone=skel:Bone(i)
      bonetable[i] = {}
      bonetable[i].bone = mybone
      bonetable[i].name = mybone:Name()
      bonetable[i].pos = mybone.fPos
      bonetable[i].ang = mybone.fAngle
This will create a table indexed by the bone ID. You match the ID of the bone to the table much more easily.
you would still use the name to compare the bones to control them, but you want to make sure that the index is unique.
With this table you can even load in the parent bone matching pairs if you want. You can create what ever items you need to store stuff.

Since the table above probably doesn't have a sequential index you can use lua pairs or ipairs to run through it:

Code: Select all

	for index,value in ipairs(bonetable) do
		local bone = bonetable[index].bone
		local angle = bonetable[index].angle
	end
Since we stored the actual bone item in the table you don't need to do a lot to get that bone item. The angle value in the table is the value that was put in there when the table was created. You could then compare the angle value of the frame you got the value to the frame you are on... sheesh... this is getting complicated. :)

The other thing to consider is storing the properties of previous frames. Not sure why you need to do that but if you do I think maybe you should use the fAnimAngle or fAnimPos which requires a different way of getting that info, but it allows you to specify a specific frame. You don't even need to store it in a table because you can get the fAnimAngle of the previous frame just by using frame-1 as the frame.

This is how you get the fAnimAngle value for a specific frame:

Code: Select all

local animAngle = mybone.fAnimAngle:GetValue(frame number)
mybone.fPos or mybone.fAngle will always get the value of the frame you are on. You can set this value without creating keys but you have to be very careful because if you change the position or angle of a bone on a frame based on the value that changes it will accumulate and you can end up with a bone spinning or moving off screen because the value changes, gets reevaluated over and over (I've made this mistake many times).

I wrote this pretty fast from memory without testing everything... I am hoping this info is correct.
I don't have time right now to figure out your script, but it's simple enough I may poke through it in the next few days.
User avatar
heyvern
Posts: 7035
Joined: Fri Sep 02, 2005 4:49 am

Re: A BONE CONTROL SCRIPT (NEEDS WORK!)

Post by heyvern »

Well I couldn't resist.

Here's my streamlined interpretation of your previous script. I don't know exactly what you need it to do or why you needed to store the previous frame position of the bones.

I basically eliminated everything, including the global table. The script works without storing anything in a table. It just gets all the info based on the matching bone names in child and parent layers.

The problem is, you still can't control the bones exactly as you expect if the parenting isn't the same. With a bit of effort that can probably be fixed as well. If the parent bones chaining or parenting isn't the same the you would need to do a bunch of math stuff with the transform matrix to get the correct values. This would just be a bunch of "math" applied to the angles and position values before applying them to the controlled child bones.

You would need to check if the controlling bone and controlled bones don't have the same parent hierarchy and then apply different calculations on the pos and angle values.

I also removed a "break" in the bone loop. Maybe this was for testing purposes not sure. If you break in that spot it would seem to me to break out of the loop when there might be more bones to find. Just guessing. it didn't really have any effect so I just took it out.

Also you will see I used the fAnimAngle instead of fAngle towards the end of the script. I didn't have to do that. Either way works, it's the same value. But as I said previously the fAnimAngle allows you to get the value from ANY frame. fAngle is only the current frame. I wasn't sure why you wanted the previous frame value. This way you could use a different frame's value by changing the frame to whatever you want, like frame-1 or whatever.

Code: Select all

function LayerScript(moho)
   local skel = moho:Skeleton()
   local skelpar=moho:ParentSkeleton()
   local frame = moho.frame
   if (skel == nil) then
      print("No skeleton found in layer")
      return
   end
   if (skelpar == nil) then
      print("No skeleton found in parent layer")
      return
   end
   for i=0, skel:CountBones()-1 do
      local mybone=skel:Bone(i)
      for j=0, skelpar:CountBones()-1 do
         local parbone=skelpar:Bone(j)
         if (mybone:Name() == parbone:Name()) then
            mybone.fStrength = parbone.fStrength
            mybone.fOffset = parbone.fOffset
            mybone.fLength = parbone.fLength
            mybone.fOffset = parbone.fOffset
            if (frame>1) then
               local posTemp = mybone.fAnimPos:GetValue(frame)
               
               mybone.fPos.x = mybone.fPos.x + (parbone.fPos.x - posTemp.x)
               mybone.fPos.y = mybone.fPos.y + (parbone.fPos.y - posTemp.y)
               mybone.fAngle = parbone.fAngle
               mybone.fScale = parbone.fScale
            end
         end
      end
   end
   skel:UpdateBoneMatrix()
end

This version of the script includes the table creation. Like I said it isn't required to do the controlling. Not sure exactly what you want that info for that you can't just get directly from the actual bones.

Code: Select all

function LayerScript(moho)
   local skel = moho:Skeleton()
   local skelpar=moho:ParentSkeleton()
   local frame = moho.frame
   if (skel == nil) then
      print("No skeleton found in layer")
      return
   end
   if (skelpar == nil) then
      print("No skeleton found in parent layer")
      return
   end
   local bonetable = {}
   for i=0, skel:CountBones()-1 do
      local mybone=skel:Bone(i)
      for j=0, skelpar:CountBones()-1 do
         local parbone=skelpar:Bone(j)
         if (mybone:Name() == parbone:Name()) then
            
--            Populate the table data
            if (bonetable[i] == nil) then
				bonetable[i] = {}
				bonetable[i].bone = mybone
				bonetable[i].name = mybone:Name()
				bonetable[i].parent = parbone
				bonetable[i].pos = mybone.fPos
				bonetable[i].angle = mybone.fAngle
            end
            
            local name = mybone:Name()
                        
            mybone.fStrength = parbone.fStrength
            mybone.fOffset = parbone.fOffset
            mybone.fLength = parbone.fLength
            mybone.fOffset = parbone.fOffset
            if (frame>1) then
               local posTemp = mybone.fAnimPos:GetValue(frame)
               
               mybone.fPos.x = mybone.fPos.x + (parbone.fPos.x - posTemp.x)
               mybone.fPos.y = mybone.fPos.y + (parbone.fPos.y - posTemp.y)
               mybone.fAngle = parbone.fAngle
               mybone.fScale = parbone.fScale
            end
         end
      end
   end
   skel:UpdateBoneMatrix()
end
dkwroot
Posts: 677
Joined: Thu May 02, 2013 6:56 am
Location: USA
Contact:

Re: A BONE CONTROL SCRIPT (NEEDS WORK!)

Post by dkwroot »

Vern, I tried out the script you showed and it goes crazy on me. I tried releasing the layers, but it didn't help. Sometimes objects just fly off the screen with it on, so I'm not sure what's going on there. What I have found is that using fAnimPos or fAnimAngle makes the software act very strange. I'm currently using the 64-bit version of Anime Studio 9.2, so there might be some software differences between us or something.

Anywho, here's a vid to show what I got so far. Hopefully this will clear everything up on what my goal is and how far along I am with it. I'm almost totally done with this, but I'm missing one piece.

http://www.youtube.com/watch?v=R9tL30tm ... e=youtu.be

**Here's a random question. How do you embed youtube videos? I tried the youtube button with the address above, but it doesn't work.**


The thread I mention in the video is viewtopic.php?t=1480

Code: Select all

function LayerScript(moho)

   local skel = moho:Skeleton()
   local parent_skeleton=moho:ParentSkeleton()
   local frame = moho.frame
   
   
   if (skel == nil) then
      return
   end
   
   if (parent_skeleton == nil) then
      return
   end
   
   for i=0, skel:CountBones()-1 do
      local child_bone=skel:Bone(i)

      for j=0, parent_skeleton:CountBones()-1 do
         local parent_bone=parent_skeleton:Bone(j)

         if (child_bone:Name() == parent_bone:Name()) then
            
            child_bone.fStrength = parent_bone.fStrength
            child_bone.fLength = parent_bone.fLength
            child_bone.fOffset = parent_bone.fOffset
			child_bone.fAngle = parent_bone.fAngle
			child_bone.fScale = parent_bone.fScale
			
            if (frame>0) then
			
				local origin = LM.Vector2:new_local()
				local bonemoved = LM.Vector2:new_local()
				local origin2 = LM.Vector2:new_local()
			
				origin:Set(0,0)
				parent_bone.fRestMatrix:Transform(origin)
				
				bonemoved:Set(0,0)
				parent_bone.fMovedMatrix:Transform(bonemoved)
				
				local dxy = origin - bonemoved
				
				
				
				if (child_bone.fParent < 0 ) then
					origin2:Set(0,0)
					child_bone.fRestMatrix:Transform(origin2)
					child_bone.fPos.x = origin2.x - dxy.x
					child_bone.fPos.y = origin2.y - dxy.y
					
				else
					--THIS PART WOULD ALLOW CONTROL BONES TO MOVE NESTED BONES THAT ARE LINKED
					--UNFORTUNATELY, I HAVE YET TO MAKE IT WORK.
					--local loc_parent = skel:Bone(child_bone.fParent)
					--local invMatrix = LM.Matrix:new_local()
					--origin2:Set(0,0)
					--invMatrix:Set(loc_parent.fRestMatrix)
					--invMatrix:Invert()
					--invMatrix:Transform(origin2)
					
					--child_bone.fPos.x = origin2.x - dxy.x
					--child_bone.fPos.y = origin2.y - dxy.y
					
				end
			break
            end
		break
        end
	
	end
   
   skel:UpdateBoneMatrix()
end
end
User avatar
heyvern
Posts: 7035
Joined: Fri Sep 02, 2005 4:49 am

Re: A BONE CONTROL SCRIPT (NEEDS WORK!)

Post by heyvern »

Okay, I think I see now what you want to do. It's actually a pretty good idea.

I will try and set up a file just like yours from the video. I have a feeling I could simply modify my existing switch control script to do what you want and will give it a shot.

I think the reason my script worked for me and didn't for you is that my test file is REALLY REALLY simple. It is simply two identical bone layers, but one is a child of the other. So the names positions and parenting are 100% identical.

I really like your idea about the controlling bones not being parented and moveable independantly of how the child or controlling bone layers are set up. This should be doable because then position of the bones would simply be ignored. I will watch your video more carefully so I get it right.

p.s. For youtube you only need to paste in the video id between the youtube brackets:

Code: Select all

[youtube]R9tL30tmT5c[/youtube]
dkwroot
Posts: 677
Joined: Thu May 02, 2013 6:56 am
Location: USA
Contact:

Re: A BONE CONTROL SCRIPT (NEEDS WORK!)

Post by dkwroot »

When I said that I wanted to combine our scripts, I meant use them together and not literally combine them. My script has to be placed on each layer, so it's probably not a good idea to use the switch layer script with it since that would be a lot of redundant code.

Basically, the switch layer script gets placed on a master bone at the top of all the layers. Then my bone script gets placed on each of the subordinate bone and switch layers below it. This allows all of the nested bones to be controlled by a small number of master bone layers at the top, while your switch layers control all the nested switches below.

Anyway, I think this is pretty much done. I may make an alternate version of this script that allows master control bones to control the motion of nested bones that are chained together. This might take a while though, since I'll have to figure out how to undo the coordinate system change that was created by the bone parenting thing.

I'm majoring in Mathematics, so the math regarding all of this isn't a problem. Most of my troubles arise from trying to understand how to use the API and exactly how the matrices are organized. From what I can tell, parenting a bone to another bone in a chain, causes the child bone to change its coordinates to reference the parent. The parent bone matrix is then transformed so that it's X and Y axis become <0,0>. The program does this so that it doesn't have to hold variables when it does it's vector math. This causes problems when trying to reference the child bones in the bone chain, since they no longer reference the global position.

**Random question: I need to know if the fRestmatrix of a bone is altered when it's placed in a bone chain.

I'm honestly thinking about just ditching their matrix system and making my own system from the ground up. At least that way, I'll know what all the functions do and how everything is organized. That would be a pain in the rear though. I'd having to make a new tool to assign relationships between bones as well, that or I'd have to resort to doing something like naming the bones in order and then making loops that check for it.


ALSO, did you notice that this script allows you to use nested smart bones? Finally, smart bones can be fully incorporated!

ALSO - ALSO, my initials are DR ... so the name of this script is going to be dr_bones

Image
User avatar
heyvern
Posts: 7035
Joined: Fri Sep 02, 2005 4:49 am

Re: A BONE CONTROL SCRIPT (NEEDS WORK!)

Post by heyvern »

Yes, bone parenting will effect the rotation and position of the child bones.

For example, if a bone is rotated a certain amount and then it's "attached" or becomes a child of another bone, the rotation VALUE will change based on the parent. AS maintains the visual orientation of the child bone when it is parented to a bone, but the actual value will change based on the parent/s rotation.

A bone postion and rotation always starts at 0 based on the parent. So if a bone is rotated 45 deg and is parented to a bone that is rotated 90 deg, the child bone will not visually change rotation but the rotation value itself changes to 325 deg to compensate for the parent bone rotation. Bone position is also related to parenting. A child bone position is always based on 0,0. If the bone is not parented at all the position is based on the layer origin as 0,0. If the bone has a parent the origin is the BASE of the parent bone. So to have a bone start exactly at the tip of the parent, the x value of the position is equal to the length of the parent and y is 0.

I have done a lot of bone and bone parenting scripting. It does get a bit complicated. Sometimes I have to calculate the rotations all the way up the chain with an iterative looping function looking for all the parent bones to get the "real" rotation and position. I had to do this with an "aim" script I wrote to aim one bone at another bone, unfortunately I am absolutely TERRIBLE with complex math involving angles, pi and matrices, etc. When I figure something complex out I usually forget it very quckly. :) I will drag out that aim bone script and see if any of it could help you with this. It was really tricky and involved things like pi and other icky angly type mathy things. :)
chucky
Posts: 4650
Joined: Sun Jan 28, 2007 4:24 am

Re: A BONE CONTROL SCRIPT (NEEDS WORK!)

Post by chucky »

Just looking at the thread, check this out , I posted September last year.
:D


I was all a bit clunky in the end I got bored of all the layers and rigging. :(

I should say, though, I think what you are doing is very cool . Nice job.
dkwroot
Posts: 677
Joined: Thu May 02, 2013 6:56 am
Location: USA
Contact:

Re: A BONE CONTROL SCRIPT (NEEDS WORK!)

Post by dkwroot »

chucky wrote:Just looking at the thread, check this out , I posted September last year.
:D


I was all a bit clunky in the end I got bored of all the layers and rigging. :(

I should say, though, I think what you are doing is very cool . Nice job.
Thanks!

I updated the first post. The script is complete. I made two variations of it so hopefully it works well for everyone.

/cheers
Post Reply