Little Scripting Doubts and Curiosities Site :)

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

Moderators: Víctor Paredes, Belgarath, slowtiger

User avatar
Rai López
Posts: 2228
Joined: Sun Aug 08, 2004 1:41 pm
Location: Spain
Contact:

Little Scripting Doubts and Curiosities Site :)

Post by Rai López »

Well, here is the first:

- fTempPos (LM_Vector2): a temporary variable for storing position, useful when transforming points

I always have been very curious about that "temporary" comands cause I can imagine something but I have not a real concept of them and... well, I'd be very happy if someone could give me some info or clue about that and possible applications :), if you can --> THANKS! :D If not... COME OUT OF MY TOPIC! :x Jaja... :wink:
User avatar
Rai López
Posts: 2228
Joined: Sun Aug 08, 2004 1:41 pm
Location: Spain
Contact:

Post by Rai López »

HELLO! :) Someone knows if Layer Visisbility state (I mean, when a layer has the EYES in Layer Window or not) is accesible by scripting interface? I've been searching but any comand seems to correspond with this feature... Any clue? THANKS! :D
User avatar
Rai López
Posts: 2228
Joined: Sun Aug 08, 2004 1:41 pm
Location: Spain
Contact:

Post by Rai López »

...OTHER! (HI! :) ) Well, this one is a little more serious and important to me... The case is that I always have had a lot of problems to understand how that "_Vector2" functions works and no matter how much I try it it's simply impossible to me can access to the two values se pa ra te ly... I have been googling and studing all that scripts where it is called (select/translate bones, i.e, and many others, but all seems to be mixed there and with all that information result to me in a total mess :(, plus they are not Embeded Scripts and I lost my self so easily...

Well, basically I always have needed can treat the two axis of the movement of a bone or point individually, I mean if I use the "fPos" value to copy the position of a certain bone to another I am copy the X & Y values and I don't know how I can stablish variations in only one of the axis... So well, if somebody could give me a little explanation or advice about this issue I'd be very GRATEFUL :) ...BYE!

PD: ...VERY! :D
User avatar
7feet
Posts: 840
Joined: Wed Aug 04, 2004 5:45 am
Location: L.I., New Yawk.
Contact:

Post by 7feet »

I'm feeling a little fuzzy on the proper terms this second, but here goes-

A Vector2 object has 2 "subvalues" to it, "x" and "y". So in the example you are asking about, say you have something like this:

Code: Select all

local currentBone = skel:Bone(x)
local currentBonePos = currentBone.fpos
local itsXposition = currentBonePos.x
local itsYposition = currentBonePos.y
As I understand it, in this case (and really, it's a pretty basic thing in Lua), almost everything is a table. The bone object is a table that includes an index called fPos. That particular table contains sub-indexes called x and y.

I'll have to look it up for the particular syntax, but I think you could also find, say the "x" as currentBone["fpos"]["x"]. I think thats right. The "." is just another way of laying out the nested elements of a table. In the above example, you cpuld condense it all to

Code: Select all

local itsXposition = skel:Bone(x).fPos.x
Whenever you have a Vector2 object, you always have that x and y underneath it. For Vector3, its x,y,and z. For RGB_Color its, r, g and b, etc.

Now thats all for frame zero. If it's an animated value, there's more stuff to do...

If that doesn't make sense, I'll try again whenever I wake up. And try to go into some more depth anyway. If I'm getting you correctly, it's an area that confused the hell out of me at first.
User avatar
Rai López
Posts: 2228
Joined: Sun Aug 08, 2004 1:41 pm
Location: Spain
Contact:

Post by Rai López »

...Ey! 7FEET!!! :D THANK YOU VERY MUCH! And SORRY for your time too, yes... But at least after all the afternoon I'm GETTING results! :D And all just before I went to desist... :)

...Well, finally this is the aspect of the part of your SF_ControlBone_ctrl.lua that I have modified with succes (for now... :roll: )

Code: Select all

	local position = LM.Vector2:new_local()
	position.x = masterBonePos.x
	position.y = masterBonePos.y
   ----------------------------------------------------------------
   --Control it
   ----------------------------------------------------------------
	if (moho.frame ~= 0) then
	local controlledbone = skel:Bone(controlledBoneID)
	controlledbone.fAngle = ctrlAng + masterBoneAngle
	
	controlledbone.fPos.x = ctrlAng + position.x
	controlledbone.fPos.y = ctrlAng + position.y
	
	controlledbone.fScale = ctrlScl + masterBoneScale
	moho:Skeleton():UpdateBoneMatrix()
	end
end
...I'm not sure if this is the best way but it WORKS! and I'm totally free now to change the way Master bones movement affect Controlled bones axis position se pa ra te ly :), and well, this is VERY important cause after the last 5.3.1 Moho update, the movement of Controled bones result inverted when you rotate (-180º i.e.) or Flip sub bone controlled Layers, so I had to see how and in a second the SO wanted scripts became practically useless to me... just after all that effort and time to get they works, you remember? Uf... When I discovered it was for me a great upset :( and I abandoned the scripts pluged into something like a little depression... WELL! But now seems that I can mend it so --> :D, maybe adding and modificating some other (stoled) 7feet lines of code like:

Code: Select all

-- has the layer been flipped in a way we need to know about?
local flipH = moho.layer.fFlipH.value
local flipV = moho.layer.fFlipV.value
local layerFlipped = (flipH and not flipV) or (flipV and not flipH)

if layerFlipped then
	position.x = -position.x
end
Well, this is of your great SF_LayerSound.lua script and I must go on investigating a little more... Something more complicated can be resolve the Layer Y/X Rotation issue but I think I could get it too with some luck and patience... We'll see... WELL! THANKS for all (your advice of think in "_Vector2" objects like a table was the key :)) and althought I'll treat to resolve (as possible...) all the problems by my self don't rule out have to make another little querys in the future... hmmm... SORRY in advance if it occurs :roll: & CIAO!
Last edited by Rai López on Fri Mar 03, 2006 7:17 pm, edited 1 time in total.
User avatar
Rai López
Posts: 2228
Joined: Sun Aug 08, 2004 1:41 pm
Location: Spain
Contact:

Post by Rai López »

HI AGAIN! Uf... This is that I have at the moment :) :

Code: Select all

function LayerScript(moho)
	if (moho:CountBones() < 1) then
		return false
	end
	local skel = moho:Skeleton()
   -------------------------------------------------------------
   --Find the Controlled Bone - only frame 0
   -------------------------------------------------------------
	if (moho.frame == 0) then
		local layer = moho.layer
		local controlledBone = nil
	       
		for count = 0, (skel:CountBones() - 1) do
			local cBone = skel:Bone(count)
			local name = cBone:Name()
			if (string.sub(name, -5) == ".ctrl") then
				controlledBoneID = skel:BoneID(cBone)
				controlledBone = cBone
			end
		end
		if (controlledBone == nil) then
			print("No controlled bone found")
			return
		end
		ctrlAng = controlledBone.fAnimAngle:GetValue(0)
		ctrlPos = controlledBone.fAnimPos:GetValue(0)
		ctrlScl = controlledBone.fAnimScale:GetValue(0)
	end
	
	local position = LM.Vector2:new_local()
	position.x = masterBonePos.x
	position.y = masterBonePos.y
	
	-- has the layer been flipped or rotated in a way we need to know about?
	local flipH = moho.layer.fFlipH.value
	local flipV = moho.layer.fFlipV.value
	local layerFlippedH = (flipH and not flipV) or (flipV and flipH)
	local layerFlippedV = (flipV and not flipH) or (flipV and flipH)
	
	local rotationY =moho.layer.fRotationY.value
	-- print (math.deg (rotationY))
	local rotationX =moho.layer.fRotationX.value
	-- print (math.deg (rotationX))
	
	if layerFlippedH or rotationY < math.rad (-90) or rotationY > math.rad (90) then
		position.x = -position.x
		masterBoneAngle = -masterBoneAngle
	end	
	if layerFlippedV or rotationX < math.rad (-90) or rotationX > math.rad (90) then
		position.y = -position.y
		masterBoneAngle = -masterBoneAngle
	end
   ----------------------------------------------------------------
   --Control it
   ----------------------------------------------------------------
	if (moho.frame ~= 0) then
	local controlledbone = skel:Bone(controlledBoneID)
	controlledbone.fAngle = ctrlAng + masterBoneAngle
	
	controlledbone.fPos.x = ctrlPos.x + position.x
	controlledbone.fPos.y = ctrlPos.y + position.y
	
	controlledbone.fScale = ctrlScl + masterBoneScale
	moho:Skeleton():UpdateBoneMatrix()
	end
end
Basically experiments and nothing definitive... As you can see the script growns and growns and I don't know if this is the best way to can solve the directions problem, but well, at least I'm getting some results 8) ...It's a little mesh, and more when there are several layers nested, and unnespected results when flipping and X/Y rotations are combinated, really can be a madness, but well, meantime others ideas come (I hope :roll:) could be like a "provisional" solution for now... Really I don't know if could be another more "intuitive" and simple way to resolve it (based in camera orientation or global parameters or something...) and, of course, if someone has any suggestion I'm all ears :) ...GOOD NIGHT!
User avatar
Rai López
Posts: 2228
Joined: Sun Aug 08, 2004 1:41 pm
Location: Spain
Contact:

Post by Rai López »

...HELLO! And yes, a little doubt more... Well, this is :arrow: somebody knows something about the way to obtain the 2D position of a certain bone in a layer?? I mean, if I use "fPos/fAnimPos" values it only would work for root bones, cause if I want to know the position of a child bone using this entries I obtain the position of the bone respect of his parents and not the "real" position in the same layer... Well, I thought that should be an easy way but I've not been able to find it yet in the scripting manual and now even I'm not sure that it really exists, so... well, any help/clue it'd be (of course) very WELCOMED! (Please :))
User avatar
7feet
Posts: 840
Joined: Wed Aug 04, 2004 5:45 am
Location: L.I., New Yawk.
Contact:

Post by 7feet »

As far as I know, there's no easy way to do it. A "GetFullTransform" functions for bones would be the trick. Lacking that, to simplify somwhat, you need to parse back up the bone chain. Take the current bones position, and transform that against the the parent bones position and angle, keeping length in mind. And then up the chain to the primary bone. Don't have any algorithms to do it in front of me, haven't neeed them. But it shouldn't be very terrible vector math. Well, unless you have multiple nested bone layers with 3d rotations and scalings and... I could see it getting a bit scary pretty fast.

I thought of writing some stuff to figure out things like that for a collision detection bit, but I didn't really need it, and it would be more work than I wanted to put in on something speculative. Don't tend to write extensions until I really need them. But for a single layer, it shouldn't be all that awful to work out a bones absolute position (in that layer) based on the position, original length, scaling and angle. I have a link around to a really good site (lots of 2D and 3D vector basics) that I used to puzzle out my SOS script, I'll have to dig it out for you, allowed me to do it at all.
User avatar
Fazek
Posts: 246
Joined: Thu Apr 13, 2006 1:37 pm
Location: Hungary
Contact:

Post by Fazek »

This is a sample program I wrote to find how to retrieve the screen coordinates of a bone. I think it is working good even in embedded situations and calculates both the internal and pixel coordinates.

Code: Select all

function xDrawAllBones(moho,view)
	local bone,skel

	if (moho.layer:LayerType() == MOHO.LT_BONE) then
		skel= moho:Skeleton()
	else
		skel= moho:ParentSkeleton()
	end

	if (skel == nil) then return end

	local gfx= view:Graphics()
	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 gm= LM.Matrix:new_local()
	gm:Set(gfx:CurrentTransform())
	gm:Invert()

	gfx:SetSmoothing(true)
	gfx:SetColor(255,0,0)

	local m= LM.Matrix:new_local()
	moho.layer:GetFullTransform(moho.frame,m,moho.document)

	for i= 0,skel:CountBones() - 1 do
		bone= skel:Bone(i)

--root
		if (moho.frame == 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(moho.frame))

		if (moho.frame == 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)
--draw line
		gfx:WorldToScreen(vec1,pt1)	--screen coordinates
		gfx:WorldToScreen(vec2,pt2)

		gfx:Push()
		gfx:ApplyMatrix(gm)		--convert to identity matrix

		gfx:MoveTo(pt1.x,pt1.y)
		gfx:LineTo(pt2.x,pt2.y)
		gfx:Pop()
	end

	gfx:SetSmoothing(false)
	view:Refresh()
	LM.Snooze(1000)
end

- - - Fazek
User avatar
Rai López
Posts: 2228
Joined: Sun Aug 08, 2004 1:41 pm
Location: Spain
Contact:

Post by Rai López »

And... here I am and here is my :arrow: THANK YOU!!! I've been testing it and this is an :shock: IN-CRE-DI-BLE :shock: work! Uf, I can't believe I don't discover your post until last night... I'm sure this will have a lot of possible applications and for the time being it will be able to me can finish my "Show Keyed" tool that I still had as impossible... Well, as I said, I have been testing it in all the situations and the only one problem that I have observed actually seems to be when I scale a bone/s in the chain, since all the subsequent affected drawed lines start to be upset until the next unScaled bone of the chain... Well, I'll try to search a possible solution obtaining and multiplying the scaling factor for affected bones but how I imagine that it could be more complicated than that... well, any clue or help (...more? Glup :oops:) always would be welcomed :)

Ah! And...
7feet wrote:I have a link around to a really good site (lots of 2D and 3D vector basics) that I used to puzzle out my SOS script, I'll have to dig it out for you, allowed me to do it at all.
...PLEASE 7feet! (and SORRY!) But although I've been out this topic for a time (probably cause the removal mess...) I'm still interested on all that you say so, if you don't mind, it'd be for me (as always) like a pleasure can acces to all that knowledge bases although I don't will be able to take advantage of it as be expected or as I'd want :roll: ...Well, THANK YOU very much too and... Oh! PLEASE, do some work that requires Collisions (please :D) ...CIAO to both! :)
User avatar
Rai López
Posts: 2228
Joined: Sun Aug 08, 2004 1:41 pm
Location: Spain
Contact:

Post by Rai López »

...EY! HI! :) After several hours... Do you think that simply modifing this 47 line of your code in this way...

Code: Select all

vec2:Set(bone.fLength * bone.fScale,0)
...should resolve the scale problem? I've obtaining best results after modification but seems that still could be some problem during animation... hmmm... I should experiment more but seems to me that 5:43 AM is like a good hour to go to sleep here :roll:, so... well :arrow: GOOD NIGHT!
User avatar
Fazek
Posts: 246
Joined: Thu Apr 13, 2006 1:37 pm
Location: Hungary
Contact:

Post by Fazek »

Thanks a lot!!!! I examined the problem and it seems there is a solution, see the new code below. The problem is that the scaling of the parent bone affects only the root position of the bone, but the tip is different because it keeps its direction and size regardless of the parent's scaling. So using the same transformation matrix for the two things was a wrong idea. The solution is to calculate the relative tip vector without parent scaling, and add it to the original root vector. Btw, I changed this in my Selection Tool as well, download it. Thank you again.

Code: Select all

function xDrawAllBones(moho,view)
	local bone,skel

	if (moho.layer:LayerType() == MOHO.LT_BONE) then
		skel= moho:Skeleton()
	else
		skel= moho:ParentSkeleton()
	end

	if (skel == nil) then return end

	local gfx= view:Graphics()
	local vec1= LM.Vector2:new_local()
	local vec2= LM.Vector2:new_local()
	local v= LM.Vector2:new_local()

	local pt1= LM.Point:new_local()
	local pt2= LM.Point:new_local()

	local gm= LM.Matrix:new_local()
	gm:Set(gfx:CurrentTransform())
	gm:Invert()

	gfx:SetSmoothing(true)
	gfx:SetColor(255,0,0)

	local m= LM.Matrix:new_local()
	moho.layer:GetFullTransform(moho.frame,m,moho.document)

	for i= 0,skel:CountBones() - 1 do
		bone= skel:Bone(i)

		local pBone

		if (bone.fParent >= 0) then
			pBone= skel:Bone(bone.fParent)
		end

--root
		if (moho.frame == 0) then
			vec1:Set(bone.fAnimPos:GetValue(0))

			if (pBone) then
				pBone.fRestMatrix:Transform(vec1)
			end
		else
			vec1:Set(bone.fPos)
			if (bone.fParent >= 0) then
				pBone.fMovedMatrix:Transform(vec1)
			end
		end
--tip
		vec2:Set(bone.fLength * bone.fScale,0)
		vec2:Rotate(bone.fAnimAngle:GetValue(moho.frame))

		if (moho.frame == 0) then
			vec2= vec2 + bone.fAnimPos:GetValue(0)

			if (bone.fParent >= 0) then
				pBone.fRestMatrix:Transform(vec2)
			end
		else
			vec2= vec2 + bone.fPos

			if (bone.fParent >= 0) then

				if (pBone.fScale ~= 1.0) then
					v:Set(bone.fPos)
					pBone.fRestMatrix:Transform(v)
					pBone.fRestMatrix:Transform(vec2)
					vec2= vec2 - v + vec1
				else
					pBone.fMovedMatrix:Transform(vec2)
				end
			end
		end

		m:Transform(vec1)
		m:Transform(vec2)

		gfx:WorldToScreen(vec1,pt1)	--screen coordinates
		gfx:WorldToScreen(vec2,pt2)

		gfx:Push()
		gfx:ApplyMatrix(gm)		--convert to identity matrix

		gfx:MoveTo(pt1.x,pt1.y)
		gfx:LineTo(pt2.x,pt2.y)
		gfx:Pop()
	end

	gfx:SetSmoothing(false)
	view:Refresh()
	LM.Snooze(1000)
end
- - - Fazek
User avatar
Rai López
Posts: 2228
Joined: Sun Aug 08, 2004 1:41 pm
Location: Spain
Contact:

Post by Rai López »

Fazek wrote:Thanks a lot!!!!
...Thanks? :shock: Thanks a lot???? :? ...THANKS TO YOU!!! :D For this and for make all that things that you are doing! You Scripters make this days of shortage of news so interesting :roll: ...Ah! And although I must experimenting more with the new code it seems to work perfectly! Well, this time I've added this at line 47:

Code: Select all

vec1:Set(bone.fPos + bone.fOffset)
...to take into account if a bone has Offset and avoid unwanted upsets, the problem seems to be resolved, but you can check it if you want to test if all is entirely right now... Well, and for now the only really one strange thing that I've observed is an upset when a bone in the chain uses Dynamics, but this seems to be an old internal problem so I think this couldn't have a possible solution by scripting, so I think the solution could be only in the LM (or helper) hands... Well, THANK YOU again for all this dedication, I think never could have finished (well, almost...) my Display_Keyed feature without your help :) ...CIAO!
User avatar
Rai López
Posts: 2228
Joined: Sun Aug 08, 2004 1:41 pm
Location: Spain
Contact:

Post by Rai López »

...BTW2! Any clue about this, PLEASE? Actualy if I what to test if some animatable parameter has a key I can get it, in example, using this...

Code: Select all

if (pt.fWidth:HasKey(frame)) then	
	...

end
...But now I need to know if certain point has a Curvature key and seems that I can't cause, as far as I can understand reading "Scripting Documentation" and observing other relationated tools, the Curvature parameter is treated in a very diferent way... Well, anyway I think there must be an easy way to get this and I'd be very :) GRATEFUL :) for/if any help/clue that can arrives... CIAO!
User avatar
Fazek
Posts: 246
Joined: Thu Apr 13, 2006 1:37 pm
Location: Hungary
Contact:

Post by Fazek »

About the bone offset, as I see there are two viewing modes for the bones on frame 0. It is not clear for me how to change between the normal mode and the other (with offsets and bubbles around the bones). Some tools are using this and others that, but I can't see how. Could you tell me something about this?

About the curvature, it seems to me that the curvature value belongs not to points, but curve segments. That's why it is not in the point structure, a point can use different curvatures for the belonging segments. I think there is an internal table to store the order of mesh points in the curve - you can read this with curve:Point() - and maybe the curvature channels are belonging to this - curve:GetCurvature(). I don't know too much about the real mechanism of the curvature, I am using two different spline types, one is Bezier of course, with two control points per segment and the other what has only one control point and used by Flash. This one is none of them, but maybe curvature is only a calculated value and there is something else (control point?) inside.
- - - Fazek
Post Reply