//  agDistribuidor 1.0
//  Julio 2006
//
//  Creado por agedito
//	agedito3d@agedito.com
//	http://www.agedito.com
//
//  Este script distribuye objetos entre dos objetos extremos
//  Permite distrucón lineal o usando una curva
//
// El botón bloquear nos permite que se aplique la distribución siempre sobre los mismos objetos
//  aunque no sean ya la selección activa
//
// La curva de distribución no se inicializa con los valores de los objetos actuales.
// Podemos actualizar los valores de los exremos usando el botón Leer Extremos
//
//  Posibles mejoras:
//	Que la curva que se adapte inicialmente a los objetos
//	Que la curva sea animable
//	Incorporación de los extremos a la distribución usando la curva


iz=Interfaz();

function DistObjs(aObjetos,aX,aY,aZ,lineal)
{
	
	var	min=XSIMath.CreateVector3();
	var max=XSIMath.CreateVector3();
	var dir=XSIMath.CreateVector3();
	var inc=XSIMath.CreateVector3();

	var num=aObjetos.count;
	if (num<3) return;
	oMin=aObjetos(0);
	oMax=aObjetos(1);
	min.Set(oMin.posx.value,oMin.posy.value,oMin.posz.value);
	max.Set(oMax.posx.value,oMax.posy.value,oMax.posz.value);

	dir.Sub(max,min)
	inc.Scale(1/(num-1),dir);
	for (var i=2;i<num;i++)
		{		
		if (aX) aObjetos(i).posx.value=min.x+inc.x*(i-1);
		if (aY) aObjetos(i).posy.value=min.y+inc.y*(i-1);
		if (aZ) aObjetos(i).posz.value=min.z+inc.z*(i-1);
		};}

function Interfaz()
{
	var ventana=ActiveSceneRoot.AddProperty("CustomProperty",false,"agDistribuidor");
	ventana.AddParameter3("X",siBool,0,0,1,false);
	ventana.AddParameter3("Y",siBool,1,0,1,false);
	ventana.AddParameter3("Z",siBool,0,0,1,false);	
	ventana.AddParameter3("Bloquear",siBool,0,0,1,false);
	ventana.AddParameter3("Eje",siInt4,1,0,2,false);
	ventana.AddFCurveParameter("Curva");	
	ventana.AddParameter3("Interactivo",siBool,1,0,1,false);
	ventana.AddParameter3("Bloquear",siBool,0,0,1,false);
	ventana.AddParameter3("Objetos",siString,"",0,1,false);	

	InspectObj(ventana);
	
	var aspecto=ventana.PPGLayout;
	aspecto.Clear();
	aspecto.AddTab("Lineal");

	aspecto.AddGroup("Ejes");
	aspecto.AddRow();
	aspecto.AddItem("X");
	aspecto.AddItem("Y");
	aspecto.AddItem("Z");	
	aspecto.EndRow();
	aspecto.EndGroup();
	
	aspecto.AddRow();
	aspecto.AddButton("Distribuir");
	aspecto.AddSpacer(5);
	aspecto.EndRow();
	aspecto.AddTab("Distribución");
	var valores=["X",0,"Y",1,"Z",2];
	aspecto.AddEnumControl("Eje",valores,"Eje",siControlCombo);
	aspecto.AddItem("Curva");
	aspecto.AddRow();
	aspecto.AddButton("Aplicar");
	aspecto.AddSpacer(2);
	aspecto.AddButton("Leer","Leer extremos");
	aspecto.AddSpacer(5);
	aspecto.AddItem("Interactivo");
	aspecto.EndRow();

	aspecto.AddTab("Objetos");
	aspecto.AddItem("Bloquear");
	//aspecto.AddItem("Objetos");


	aspecto.Language="JScript";
	aspecto.Logic=Objetos.toString()+Aplicar_OnClicked.toString()+Leer_OnClicked.toString()+Distribuir_OnClicked.toString()+Curva_OnChanged.toString()+Bloquear_OnChanged.toString()+DistObjs.toString();
}

function Objetos()
{
	var prop=PSet.Inspected(0);
	var col=new ActiveXObject("XSI.Collection");
	
	var pObj=prop.objetos.value;
	if (pObj=="") 
		{
		if (selection.count==0) return col;
		pObj=selection.GetAsText();
		};
	col.SetAsText(pObj);
	
	return col;
}

function Bloquear_OnChanged()
{
	var prop=PSet.Inspected(0);
	var bloq=prop.bloquear.value;
	var pObjs=prop.objetos;
	if (bloq) pObjs.Value=selection.GetAsText(); else pObjs.Value="";	
}

function Distribuir_OnClicked()
{
	var prop=PSet.Inspected(0);

	var x=prop.x.value;
	var y=prop.y.value;
	var z=prop.z.value;	

	var col=Objetos();
	DistObjs(col,x,y,z);
}

function Leer_OnClicked()
{
	var prop=PSet.Inspected(0);	
	var objs=Objetos();	
	if (objs.count<2) return;
	var curva=prop.curva.value;
	var eje=prop.eje.value;
	var claves=curva.Keys;
	var num=claves.count;
	var v=XSIMath.CreateVector3();
	
	v.Set(objs(0).posx.value,objs(0).posy.value,objs(0).posz.value);
	curva.SetKey(0,0,v(eje));
	v.Set(objs(1).posx.value,objs(1).posy.value,objs(1).posz.value);
	curva.SetKey(num-1,100,v(eje));	
}

function Aplicar_OnClicked()
{
	var prop=PSet.Inspected(0);
	var curva=prop.curva.value;

	var objs=Objetos();

	var num=objs.count;
	if (num<3) return;
	var eje=prop.eje.value;
	var inc=100/(num-1);
	for (var i=2;i<num;i++)
		{
		var t=(i-1)*inc;		
		var pos=curva.Eval(t);
		if (eje==0) objs(i).posx.value=pos;
		if (eje==1) objs(i).posy.value=pos;
		if (eje==2) objs(i).posz.value=pos;
		};
}

function Curva_OnChanged()
{
	var prop=PSet.Inspected(0);
	var interactivo=prop.interactivo.value;
	if (!interactivo) return;
	Aplicar_OnClicked();
	
}
