plugin Helper Interpolator\
	name:"Interpolator"\
	extends:BoxGizmo\
	replaceUI:true\
	classID:#(0x89aa7d8d, 0x65e38721)
(

fn generatescript = 
	(
	controllerstring = "" as stringstream
	format "-- this script will fail if you rename the object\n" to:controllerstring
	format "-- if necessary change singlequoted text in the \n-- following line to refer to the renamed object\n" to:controllerstring
	format "tension = $'%'.tension\n" $.name to:controllerstring
	format "fn matmult matrix n =\n\t(\n" to:controllerstring	
	format "\treturn matrix3 \\\n" to:controllerstring
	format " \t\t(matrix.row1 * n)\\\n\t\t(matrix.row2 * n)\\\n\t\t(matrix.row3 * n)\\\n\t\t(matrix.row4 * n)\n\t)\n" to:controllerstring
	format "parentspace = $'%'.objecttransform\n" this.ParentObj.Name to:controllerstring
	orient = #([1,0,0],[0,1,0],[0,0,1])[this.axis]
	format "a = matrixfromnormal %\n" orient to:controllerstring
	format "b = orthogonalize ($'%'.transform * inverse parentspace)\n" This.SiblingObj.name to:controllerstring
	format "a1 = matmult a tension\n" to:controllerstring
	format "b1 = matmult b (1 - tension)\n" to:controllerstring
	format "orthogonalize (a1 + b1)\n" to:controllerstring
	$.rotation.controller = rotation_script()
	$.rotation.controller.script = (controllerstring as string)
	)

fn HasChildren obj = ((obj.children).count != 0)	
fn OKsib obj = (obj.parent == this.ParentObj)
fn HasParent obj = (obj.parent != undefined)



parameters main rollout:params
(
height	type:#WorldUnits	ui: height
width	type:#WorldUnits	ui: width
length	type:#WorldUnits	ui: length
tension	type:#float	ui:tension	animatable:true
axis	type:#integer	ui:axis default: 3
stub	type:#node


on height set val do
	(
	delegate.height = val
	if $ != undefined do $.objectoffsetpos = [0,0,(-.5 * val)]
	)
on width set val do
	(delegate.width = val)
on length set val do
	(delegate.length = val )
	
)


rollout params "Interpolator"
	(
	group "Interpolator Object"
		(
		spinner height "Height " align:#center fieldwidth:40
		spinner width	"Width " align:#center fieldwidth:40
		spinner length	"Length" align:#center fieldwidth:40
		)
	group "Tension"
		(
		Spinner	tension_spn	type:#float range:[0,1,.5] across:2 fieldwidth:32  offset:[-32,3]
		Slider	tension	type:#float	range:[0,1,.5] width:110 offset:[-30,0]
		)
	group "Axis"
		(
		radiobuttons Axis labels:#("X  ","Y  ","Z  ")
		)
		

	on tension_spn changed val do
		(if tension.value != val do tension.value = val)
	
	on tension changed val do
		(if tension_spn.value != val do tension_spn.value = val)
	
	
	on Params open do
		(
		this.Attach.update()
		
		)
	)	

parameters Attachments rollout:Attach
	(
	
	parentOBJ	type:#node ui:pickParent
	SiblingOBJ	type:#node ui:PickSib

	on ParentObj set obj do
	(
	if obj == undefined then 
		(
		This.Attach.Update()
		)
	else
		(
		if (obj.children).count == 1 then
			(this.SiblingObj = obj.children[1])
		This.Attach.Update()
		)
	)
	on SiblingObj set obj do
		(
		if obj == undefined then 
			(This.Attach.Update())
		else
			(
			if This.ParentObj != obj.parent do (this.parentObj = obj.parent)
			$.position = Obj.transform.row4 + [0,0,.1]
			$.parent = This.Parentobj
			This.Attach.update()
			Generatescript()
			)
		)

	)

rollout Attach	"Attachment"
	(
		pickbutton PickParent "pick upper bound" filter:HasChildren
		pickbutton PickSib  "pick lower bound"filter:HasParent
		
		fn update = 
			(
			print "updating"
			try (Pickparent.Caption = this.parentOBJ.name)
			catch (Pickparent.Caption = "pick upper bound")
			try (pickSib.Caption = this.siblingObj.name)
			catch (picksib.Caption = "pick lower bound")
			)
	on attach open do (update())
	)	
	
tool create 

	(
	on mousepoint click do
		(
		case click of
			(
			1: (
				nodeTM.translation = gridpoint
				)
			3: #stop
			)
		)
	on mouseMove click do 
		(
		case click of 
			( 	
			2: (
				width = abs gridDist.x
				length = abs gridDist.y
				) 
			3: (
				height = abs gridDist.z
				objectoffsetpos = [0,0,-.5 * gridDist.z]
				) 
			) 
		)
	)
on create do
	(
	 tension = .5
	)
)
	