/* NAME = body.func */
/* Wed 21-11-2024 (anyflo.24.03) Michel Bret */

/*
body(-1): init
body(-1,option,1): init
body(num): build body_meta(num)
if(num==-1) body([1,Max_Nb_Body])
must be defined Nb_Body,Nb_Body1
*/

/* MAIN PROGRAM */
/* ============ */

body(inc0,option,flag)
{
extern Nb_Body,Max_Nb_Body;

	if(inc0<0)
	{
		body_set_param(inc0,option);

		if(flag!=NIL)
		{
			for(i=0,Max_Nb_Body-1)body(i,option);
		}
		return;
	}
	nb=Nb_Body[2];
	body_option(option,inc0);
	body_build(inc0);
	body_anc(inc0);
	set_rot(inc0);
	body_adjustment(inc0);
	body_set_limit_rota();
	body_genetic(inc0);
	body_attach(inc0);
}

/* EXTERNS */
/* ======= */

body_externs()
{
extern C_Y,DD,D1,D2,X;
extern D,D_Wing,Inc0,Inc,Inc1,Nx1,Nx2,Sem_Help,Num,Nb;
extern Debug,Age,Sex;
extern Toe_g,Foot_g,Tibia_g,Buttock1_g,Buttock2_g,Knee_g;
extern Femur_g,Finger_g,Fingers_g,Hand_g,Radius_g,Humerus_g,Collarbone_g;
extern Blade_g,Wing_g,Tendon_g;
extern Toe_d,Foot_d,Tibia_d,Buttock1_d,Buttock2_d,Knee_d;
extern Femur_d,Finger_d,Fingers_d,Hand_d,Radius_d,Humerus_d,Collarbone_d;
extern Blade_d,Wing_d,Tendon_d;
extern Pelvis,Belly,Head,Head_Ax,Secy_Head,Face,Hair,Belt,Image_Face,Wing;
extern Thorax1,Thorax2,Thorax3,Thorax4,Nb_Spine,Num_Spine,Neck,Num_Dila;
extern X_Foot,Y_Foot,Z_Foot;
extern R_Leg,Y_Tibia,Y_Femur,Bod_Leg_g,Bod_Leg_d,Bod_Roty;
extern Z_Buttock;
extern Y_Hand,Y_Finger,R_Finger,K_Finger,Finger;
extern Y_Radius,R_Arm0,R_Arm,Y_Humerus;
extern X_Pelvis,Y_Pelvis,Z_Pelvis;
extern Y_Belly,Sex0,Sex1,Sex2,R_Sex,Erec;
extern X_Spine,Y_Spine,Z_Spine;
extern R_Head;
extern Body0,Body,Nb_Body,Num_Body,Max_Nb_Body,Nb_Body1;
extern Skin_Leg_g,Skin_Arm_g,Skin_Finger_g,Skin_Leg_d,Skin_Arm_d,Skin_Finger_d;
extern Skirt,Skirt1,Skirt2,Hat,Skin_Spine,Skin,Skin_Sex;
extern Num_Skin,Nb_Num_Skin;
extern Body_Col;
extern Col_Skin,Ext_Skin,Ext_Skin_Spine;
extern Lead_Arm_g,Lead_Arm_d,Lead_Humerus_g,Lead_Humerus_d;
extern Ang_Pelvis;
extern Num_Spine_Dynamic,Body_Dynamic,Num_Dynamic,Nb_Num_Dynamic;
extern K_Hair0,K_Hair,Col_Hair,Body_Illum_Hair,K_Strength;
extern Body_Breast0,Body_Breast;
extern Bod_Sti,Bod_Vis,Bod_Coe_Hair;
extern Robe;
extern Body_Coe,Body_Large;

extern Body_Hand_To_Hand,Body_Dist1,Body_Dist2,X1_SCA,X2_SCA,Y1_SCA,Dy1,Dy2,KR;
extern Body_Force;
extern Body_Genetic,Body_Prob,Body_Muta,Body_Size,Beast;
extern Bod_Sti,Bod_Vis,Bod_Sti_Hair,Bod_Vis_Hair,Bod_Illum,Bod_Transp;
}
body_set_param(inc0,option)
{
#include "body_externs()"

	Inc0=10000;	/* body(n+1)=body(n)+Inc0 */
	Inc=1000;	/* left=right+Inc */
	Inc1=5000;	/* skin particle=skin+Inc1 */
DD=1,1,1;
	C_Y=1;K_Hair0=1;
	D=100;	/* Base size */
	D_Wing=3*D;
	body_get_size();
	nx=6;Nx1=nx;Nx2=2*Nx1;
D1=5;D2=Nx2-1;
body_REA();	
	body_ini_param(6);
	Body_Large=0,2,1,1;
	Nb_Body=0,Max_Nb_Body,0,0;
	Num_Body=0,Max_Nb_Body,0,0;
	Age=calloc(Max_Nb_Body,18);
	Sex=Erec=calloc(Max_Nb_Body,0);
	Beast=calloc(Max_Nb_Body,1);
	K_Hair=calloc(Max_Nb_Body,K_Hair0);
	K_Strength=calloc(Max_Nb_Body,1);
	Body_Breast=calloc(Max_Nb_Body,Body_Breast0);
	Col_Hair=calloc(3*Max_Nb_Body);
	Bod_Roty=calloc(Max_Nb_Body);

	body_set_col();

/* Names and numbers of volumes */
/* ---------------------------- */
	Toe_g=11;Foot_g=12;Tibia_g=13;
	Buttock1_g=14;Buttock2_g=15;
	Knee_g=16;Femur_g=17;
	Finger_g=20;Hand_g=40;
	Humerus_g=42;Radius_g=43;
	Collarbone_g=44;Tendon_g=45;Blade_g=46;
	Wing_g=47;

	Toe_d=Toe_g+Inc;Foot_d=Foot_g+Inc;Tibia_d=Tibia_g+Inc;
	Buttock1_d=Buttock1_g+Inc;Buttock2_d=Buttock2_g+Inc;
	Knee_d=Knee_g+Inc;Femur_d=Femur_g+Inc;

	Finger_d=Finger_g+Inc;Hand_d=Hand_g+Inc;
	Radius_d=Radius_g+Inc;Humerus_d=Humerus_g+Inc;
	Collarbone_d=Collarbone_g+Inc;
	Tendon_d=Tendon_g+Inc;Blade_d=Blade_g+Inc;
	Wing_d=Wing_g+Inc;



//Wing=Wing_g,Wing_d,Skirt;
Wing=Wing_g,Wing_d;



	
	Pelvis=50;Robe=51;Belly=52;
	Thorax1=53;Thorax2=54;Thorax3=55;Thorax4=56;Neck=57;
	Head=58;Face=59;Hair=60;Image_Face=10;
	Sex0=62;Sex1=63;Sex2=64;
	Num_Spine=Thorax1,Thorax2,Thorax3,Thorax4,Neck;
	Nb_Spine=dim(Num_Spine);
	Body0=Hand_g,Radius_g,Humerus_g,Collarbone_g,
		Blade_g,Tendon_g,Toe_g,Foot_g,Tibia_g,Knee_g,
		Femur_g;
	Body0,=Body0+Inc;
	Fingers_g=[Finger_g,Finger_g+14];Fingers_d=Fingers_g+Inc;
	bod=Fingers_g,Buttock1_g,Buttock2_g;
	Body=Body0,bod,bod+Inc;
	Body,=Pelvis,Belly,Num_Spine,Head,Face,Sex0,Sex1,Sex2;

	Ext_Skin=1,1,0;Ext_Skin_Spine=1,.5,0;
	Skin_Spine=100;Skin_Sex=101;
	Skin_Leg_g=102;Skin_Arm_g=103;
	Skirt=104,105;Hat=106;Skin_Finger_g=107;
	Skin_Leg_d=Skin_Leg_g+Inc;Skin_Arm_d=Skin_Arm_g+Inc;
	Skin_Finger_d=Skin_Finger_g+Inc;
	w=Skin_Leg_g,Skin_Arm_g,[Skin_Finger_g,Skin_Finger_g+4];
	w,=w+Inc;
	Skin,=w,Skin_Sex;
	Skin,=Skin_Spine;
	Num_Spine_Dynamic=[Belly,Head];
	Body_Dynamic=Toe_g,Foot_g,Tibia_g,Femur_g,Finger_g+
		[0,14],Hand_g,Radius_g,Humerus_g;
	Body_Dynamic,=Body_Dynamic+Inc;
	Body_Dynamic,=Num_Spine_Dynamic;
	Num_Dynamic=Toe_g,Foot_g,Tibia_g,Femur_g,Hand_g,Radius_g,
		Humerus_g,Finger_g+[0,14];
	Num_Dynamic,=Num_Dynamic+Inc;
	Num_Dynamic,=Pelvis,Num_Spine_Dynamic,Sex1;
	Nb_Num_Dynamic=dim(Num_Dynamic);

	Finger=Finger_g+[0,14];
/* Sizes */
/* ----- */
	Body_Genetic=1;Body_Prob=0,1,.75,.75;
	Body_Muta=.001,.1,.005,.005;
	Body_Size=2,256,128,128;

	read image(Image_Face)name("visa.bmp");
	d=dim image(Image_Face);x=.075*d[0];
	tran(x,-100,0)image(Image_Face);
	dim image(Image_Face)=d[0,1],1;

	body_option(option);
	if(inc0<-1)
	{
		for(i=0,1-inc0)body(i);
	}
	X=-.2;
}
body_REA()
{
#include "body_externs()"

	exec(clean(read("PARAM_BOD")));
}
body_WRI()
{
#include "body_externs()"

t="Bod_Coe_Hair=",stringf(Bod_Coe_Hair),";\n";
t,="Bod_Sti=",stringf(Bod_Sti),";\n";
t,="Bod_Vis=",stringf(Bod_Vis),";\n";
t,="Body_Illum_Hair=",stringf(Body_Illum_Hair),";\n";
t,="Body_Col=",stringf(Body_Col),";\n";
t,="Body_Force=",stringf(Body_Force),";\n";
t,="Bod_Sti=",stringf(Bod_Sti),";\n";
t,="Bod_Vis=",stringf(Bod_Vis),";\n";
t,="Bod_Sti_Hair=",stringf(Bod_Sti_Hair),";\n";
t,="Bod_Vis_Hair=",stringf(Bod_Vis_Hair),";\n";
t,="Max_Nb_Body=",string(Max_Nb_Body),";\n";
t,="Bod_Illum=",stringf(Bod_Illum),";\n";
t,="Bod_Transp=",stringf(Bod_Transp),";\n";

	write(t)name("PARAM_BOD");
/*
	message("rw")text("WRITE\n",t)poi(0,Y_Menu)
		rectangle frame period(0,75)abs;
*/
}

body_get_size()
{
#include "body_externs()"

	R_Leg=.275*D;
	Z_Pelvis=2.7*R_Leg;X_Pelvis=.5*Z_Pelvis;
	Z_Pelvis=2.8*R_Leg;X_Pelvis=.5*Z_Pelvis;
//	Y_Pelvis=.8*Z_Pelvis;
	Y_Pelvis=.7*Z_Pelvis;
	X_Foot=.35*D;Y_Foot=.1*D;Z_Foot=.15*D;
//	Y_Tibia=1.1*D;Y_Femur=D;
	Y_Tibia=1.1*D;Y_Femur=.9*D;
	R_Arm=.15*D;
	Y_Hand=.33*D;
//	R_Finger=.225*R_Arm;
	R_Finger=.25*R_Arm;
	Y_Finger=.4*Y_Hand;K_Finger=.9;
	Y_Radius=.4*D;Y_Humerus=.6*D;

	Z_Buttock=.9*R_Leg;
	Y_Belly=.15*D;
	X_Spine=.3*D;Y_Spine=.65*D;
//	R_Head=.315*D;
	R_Head=.3*D;
	Ang_Pelvis=.1*PI;
	Z_Spine=.4*D;
	R_Sex=.2*R_Leg;
}

/* CONSTRUCTIONS */
/* ============= */

body_build(inc0)
{
#include "body_externs()"

//	d=body_size((0,1.1,0, 1,1.2,0),(0,.8,0, 18,1,0,
	d=body_size((0,1,0, 1,1.1,0),(0,.8,0, 18,1,0,
		30,1,0, 100,.9,0),inc0);
	Body_Coe=0,2,d,d;

	if(inc0==NIL)inc0=0;nb=Nb_Body[1];
	if(inc0>=nb)
	{
		Nb_Body[1]=nb;Sex,=0;Age,=18;Erec,=0;
	}
	t=body_size((0,1,0, 1,1.1,0),(0,.8,0, 12,.9,0, 18,1,0, 70,.9,0, 100,.8,0),inc0);
	inc1=inc0;inc0*=Inc0;Nb=0;
	body_Toe(0,1,inc0);body_Toe(1,-1,inc0);
	body_Foot(0,1,inc0);body_Foot(1,-1,inc0);
	body_Femur(0,1,inc0);body_Femur(1,-1,inc0);
	body_Knee(0,1,inc0);body_Knee(1,-1,inc0);
	body_Tibia(0,1,inc0);body_Tibia(1,-1,inc0);
	body_Buttock1(0,1,inc1);body_Buttock1(1,-1,inc1);
	body_Buttock2(0,1,inc1);body_Buttock2(1,-1,inc1);
	body_Pelvis(inc0);
	body_Belly(inc0);
	body_Spine(inc0);
	body_Collarbone(0,1,inc0);body_Collarbone(1,-1,inc0);
	body_Tendon(0,1,inc0);body_Tendon(1,-1,inc0);
	body_Blade(0,1,inc0);body_Blade(1,-1,inc0);
	body_Head(inc0);
	body_Sex(inc1);

	body_Hand(0,1,inc0);body_Hand(1,-1,inc0);
	body_Finger(0,1,inc0);body_Finger(1,-1,inc0);
	body_Humerus(0,1,inc0);body_Humerus(1,-1,inc0);
	body_Radius(0,1,inc0);body_Radius(1,-1,inc0);

	body_set_limits(inc0);
	body_Skin(inc1);
	body_Wing(0,1,inc0);body_Wing(1,-1,inc0);
	field(-1)poi(0,0,0,0,1,0)coe(.05);
	body_generate_normal();
	body_generate_normal_vertex();
	body_generate_ext();
	body_set_col();

	v=Bod_Vis[2];
	force rota vol(Body+inc0)=0,v;
	force rota add vol(Body+inc0)=0,v;
	mass vol((Num_Dynamic)+inc0)=1;
	mass vol(Finger_g+[0,14]+inc0)=1;

	body_cor(inc0);
	body_axis(inc0);
}

body_axis(inc0)
{
#include "body_externs()"

	if(inc0==NIL)inc0=0;body=Body+inc0;n=dim(body);
	axis(0,0,1)matrix vol(Body+inc0);
	f=Collarbone_g,Blade_g,Hand_g,Finger;f,=f+Inc;f+=inc0;
	axis(1,0,0)matrix vol(f);
	axis(1,0,0)matrix vol((Humerus_g,Collarbone_g)+inc0);
	axis(1,0,0)matrix vol((Humerus_d,Collarbone_d)+inc0);
}

body_Toe(inc,sens,inc0)
{
#include "body_externs()"

	b=Beast[inc];inc=inc*Inc+inc0;
	f=Toe_g+inc;ny=3;dy=.125*Y_Foot;
	body_gen_1(b*X_Foot,Y_Foot,b*Z_Foot,f,-.5*PI,Nx1,ny,sens);
	w1=vertex secy(1)vol(f);
	dila(0,0,.8)vertex(w1)vol(f);
	tran(.5*X_Foot,dy,-.25*sens*Z_Foot)vertex(w1)vol(f);
	roty(.1*sens*PI)vertex(w1)vol(f);
	w2=vertex secy(2)vol(f);
	dila(1.4,.5,.8)vertex(w2)vol(f);
	tran(.25*X_Foot,dy,-.25*sens*Z_Foot)
		vertex(w2)vol(f);
	roty(.1*sens*PI)vertex(w2)vol(f);
	w3=vertex secy(3)vol(f);
	dila(1,.85,.8)vertex(w3)vol(f);tran(0,dy,0)
		vertex(w3)vol(f);

	w=vertex secx(.5*Nx1+1)vol(f);
	tran(0,-.5*Y_Foot,0)vertex(w[1,ny])vol(f);

	limit rotz vol(f)=-.25*PI,.5*PI;
	Num,=f;Nb++;body_set_name("Toe",f,sens,inc0);
}

body_Foot(inc,sens,inc0)
{
#include "body_externs()"

	b=Beast[inc];inc=inc*Inc+inc0;
	f=Foot_g+inc;
	ny=2;
	body_gen_1(b*X_Foot,Y_Foot,b*Z_Foot,f,-.5*PI,Nx1,ny,sens);
	w=vertex secy(1)vol(f);dila(1,1,.8)vertex(w)vol(f);
	rotz(.1*PI)vertex(w)vol(f);
	w=vertex secy(2)vol(f);
	dila(1,1.75,.75)vertex(w)vol(f);
	rotz(.25*PI)vertex(w)vol(f);
	w=vertex secy(3)vol(f);
	dila(1.25,1.6,.85)vertex(w)vol(f);
	rotz(.4*PI)vertex(w)vol(f);

	w=vertex secx(.5*Nx1)vol(f);
	tran(0,-Y_Foot,0)vertex(w)vol(f);
/*
	w=vertex secx(.5*Nx1+1)vol(f);
	tran(0,-.5**Y_Foot,0)vertex(w[0])vol(f);
*/
	tran(.1*X_Foot,Y_Foot,0)vertex(w)vol(f);

	limit rotz vol(f)=-.25*PI,.5*PI;
	Num,=f;Nb++;body_set_name("Foot",f,sens,inc0);
}

body_Tibia(inc,sens,inc0)
{
#include "body_externs()"

	b=Beast[inc];inc=inc*Inc+inc0;
	f=Tibia_g+inc;ny=4;z=sens*R_Leg;
	body_gen_1(b*R_Leg,Y_Tibia,b*R_Leg,f,0,Nx1,ny,sens);

	w=vertex secy(1)vol(f);dila(.4,1,.3)vertex(w)vol(f);

	w=vertex secy(2)vol(f);
	dila(.6,1,.6)vertex(w)vol(f);
	tran(-.1*R_Leg,-.1*Y_Tibia,.05*z)vertex(w)vol(f);

	w=vertex secy(3)vol(f);
	dila(.8,1,.7)vertex(w)vol(f);
	tran(-.2*R_Leg,-.1*Y_Tibia,.1*z)vertex(w)vol(f);

	w=vertex secy(4)vol(f);
	dila(.7,1,.5)vertex(w)vol(f);
	tran(0,-.1*Y_Tibia,0)vertex(w)vol(f);

	w=vertex secy(4)vol(f);
	dila(1.2,1,1.3)vertex(w)vol(f);
	w=vertex secy(5)vol(f);
	dila(.8,1,.6)vertex(w)vol(f);
	tran(.15*R_Leg*(1,-1,0))vertex(w[0])vol(f);
	p=poi(w)vol(f);
	rotz(-.05*PI)vertex(w)vol(f)poi(p{0});

	limit rotz vol(f)=0,.75*PI;

	Num,=f;Nb++;body_set_name("Tibia",f,sens,inc0);
}

body_Knee(inc,sens,inc0)
{
#include "body_externs()"

	b=Beast[inc];inc=inc*Inc+inc0;
	f=Knee_g+inc;ny=4;
	ball(f)secy(3)dim(.75*b*R_Leg);
	Num,=f;Nb++;body_set_name("Knee",f,sens,inc0);
}

body_Femur(inc,sens,inc0)
{
#include "body_externs()"

	b=Beast[inc];inc=inc*Inc+inc0;k=.9;
	f=Femur_g+inc;ny=4;
	body_gen_1(b*R_Leg,Y_Femur,b*R_Leg,f,0,Nx1,ny,sens);

	w=vertex secy(1)vol(f);
	dila(.85,1,.7)vertex(w)vol(f);
	tran(.1*R_Leg,0,.1*sens*R_Leg)vertex(w)vol(f);
	p=poi(w[.5*Nx1])vol(f);
	rotz(.05*PI)vertex(w)vol(f)poi(p);
	if(sens>0)s=5;else s=1;
//	tran(.25*R_Leg,.15*R_Leg,0)vertex(w[s])vol(f);
	tran(.5*R_Leg,.4*R_Leg,0)vertex(w[s])vol(f);

	w=vertex secy(2)vol(f);
	dila(.75,1,.7*k)vertex(w)vol(f);
	tran(0,.1*Y_Femur,0)vertex(w)vol(f);
//	tran(.4*R_Leg,.3*R_Leg,0)vertex(w[s])vol(f);
	tran(.4*R_Leg,.25*R_Leg,0)vertex(w[s])vol(f);

	w=vertex secy(3)vol(f);
	dila(.75,1,.9*k)vertex(w)vol(f);
	tran(0,.1*Y_Femur,0)vertex(w)vol(f);

	w=vertex secy(4)vol(f);
	dila(.9,1,k)vertex(w)vol(f);
	tran(0,0,sens*.1*R_Leg)vertex(w)vol(f);

	w=vertex secy(5)vol(f);p=poi(w)vol(f);
	dila(1.1,1,1.1*k)vertex(w)vol(f);
	g=CG secy(5)vol(f);
	dila(.9,1,1.1)vertex(w)vol(f);
	rotx(-.0125*sens*PI)vol(f);

	if(sens<0)an=-.75*PI,.125*PI;else an=-.25*PI,.75*PI;
	limit rotx vol(f)=an;

	if(sens>0)
		w=vertex secx(Nx1)vol(f);
	else
		w=vertex secx(2)vol(f);
	dila(DD)vertex(w[ny-2,ny])vol(f);

	Num,=f;Nb++;body_set_name("Femur",f,sens,inc0);
}

body_buttock(x,z,f,sens,fem)
{
#include "body_externs()"

	nx=Nx1;
	ny=secy vol(fem);w=vertex secy(ny)vol(fem);
	p=poi(w)vol(fem);
	p=p-(CG(p));
	vol(f)poi(p)fac[1,nx];
	dila(x,1,z)vol(f);
}

body_Buttock1(inc,sens,inc0)
{
#include "body_externs()"

	inc0*=Inc0;inc=inc*Inc+inc0;
	f=Buttock1_g+inc;fem=Femur_g+inc;
//	body_buttock(.95,.9,f,sens,fem);
	body_buttock(1.1,.9,f,sens,fem);
dilz(1.2)vol(f);
	rotx(.05*sens*PI)vol(f);
	if(sens>0)s=Nx1;else s=2;
	dila(DD)vertex(s)vol(f);

	Num,=f;Nb++;body_set_name("Buttock1",f,sens,inc0);
}
body_Buttock2(inc,sens,inc0)
{
#include "body_externs()"

	inc0*=Inc0;inc=inc*Inc+inc0;
	f=Buttock2_g+inc;fem=Femur_g+inc;
//	body_buttock(1.3,1.2,f,sens,fem);
	body_buttock(1.35,1.2,f,sens,fem);
	rotx(.1*sens*PI)vol(f);rotz(.05*PI)vol(f);
	Num,=f;Nb++;body_set_name("Buttock2",f,sens,inc0);
}

body_Hand(inc,sens,inc0)
{
#include "body_externs()"

	inc=inc*Inc+inc0;
	f=Hand_g+inc;
	body_gen_1(1,1,1,f,0,Nx1,1,sens);
	w1=vertex secy(1)vol(f);
	dila(3.75*R_Finger,Y_Hand,R_Finger)vertex(w1)vol(f);
	dila(1,1,3)vertex(w1[.5*Nx1])vol(f);
	w2=vertex secy(2)vol(f);
//	dila(2*R_Finger,Y_Hand,1.5*R_Finger)
	dila(2*R_Finger,Y_Hand,.75*R_Arm)
		vertex(w2)vol(f);
	meta(0)force rota follow vol(f)=-.1*sens;
	if(sens<0)
		an=-.125*PI,.5*PI;
	else
		an=-.5*PI,.125*PI;
	limit rotx vol(f)=an;

	Num,=f;Nb++;body_set_name("Hand",f,sens,inc0);
}
body_Finger(inc,sens,inc0)
{
#include "body_externs()"

	inc=inc*Inc+inc0;f1=Finger_g+inc;
	cy=.8,.85,1,.75;k=1.2,1,1.2;ry=.5*sens*PI;
	for(i=0,3)
	{
		c=K_Finger;y=Y_Finger*cy[i];
		dr=.75;r=1.5*R_Finger/(2*dr);
		for(j=1,3)
		{
			if(j==3)sy=1;else sy=2;
			body_gen_1(R_Finger,y,r,f1,0,3,sy,sens);
			roty(ry)vol(f1);
			if(j<3)
			{
				w=vertex secy(2)vol(f1);
				dila(k)vertex(w)vol(f1);
			}
			dila(c,1,c)vol(f1);
			if(j==3)dila(1.2,1,.5)vertex[1,3]vol(f1);
			body_set_name("Finger",f1,sens,inc0);
			f1++;c*=K_Finger;y*=K_Finger;r*=dr;
		}
	}
/* Thumb */
	c=K_Finger;dr=.85;r=3*R_Finger/(2*dr);y=.8*Y_Finger;
	for(j=1,3)
	{
		body_gen_1(r,y,r,f1,0,3,1,sens);
		w=vertex secy(2)vol(f1);dila(k)vertex(w)vol(f1);
		if(j==1)
		{
			w=vertex secy(2)vol(f1);
			rotz(-.33*PI)vertex(w)vol(f1);
		}
		dila(c,1,c)vol(f1);
		if(j==3)dila(.5,1,1.2)vertex[1,3]vol(f1);
		body_set_name("Finger",f1,sens,inc0);
		f1++;c*=K_Finger;y*=K_Finger;r*=dr;
	}
}

body_Radius(inc,sens,inc0)
{
#include "body_externs()"

	inc=inc*Inc+inc0;
	f=Radius_g+inc;ny=3;
	body_gen_1(R_Arm,Y_Radius,R_Arm,f,0,Nx1,ny,sens);

	w=vertex secy(1)vol(f);
	dila(.5,1,.4)vertex(w)vol(f);

	w=vertex secy(2)vol(f);
	dila(.75,1,.75)vertex(w)vol(f);
//	tran(0,-.125*Y_Radius,0)vertex(w)vol(f);

	w=vertex secy(3)vol(f);
	dila(.9,1,.9)vertex(w)vol(f);
//	tran(0,-.125*Y_Radius,0)vertex(w)vol(f);

	w=vertex secy(4)vol(f);
	dila(.8,1,.7)vertex(w)vol(f);
	limit rotz vol(f)=-.75*PI,0;

	Num,=f;Nb++;body_set_name("Radius",f,sens,inc0);
}

body_Humerus(inc1,sens,inc0)
{
#include "body_externs()"

	inc=inc1*Inc+inc0;
	f=Humerus_g+inc;ny=3;
	body_gen_1(R_Arm,Y_Humerus,R_Arm,f,0,Nx1,ny,sens);
	w=vertex secy(1)vol(f);dila(.8,1,.7)vertex(w)vol(f);
	tran(R_Arm*(-.2,.15,0))vertex(w[.5*Nx1])vol(f);
	w=vertex secy(2)vol(f);
	tran(R_Arm*(-.2,.15,0))vertex(w[.5*Nx1])vol(f);
	w=vertex secy(2,3)vol(f);dila(.9,1,.8)vertex(w)vol(f);
	w=vertex secy(ny+1)vol(f);
	dila(1.5,1.75,1)vertex(w)vol(f);
g=CG vertex(w)vol(f);
rotx(.2*PI*sens)vertex(w)vol(f)poi(g);
	tran(0,0,-sens*.5*R_Arm)vertex(w)vol(f);

	limit rotz vol(f)=-.75*PI,.25*PI;

	Num,=f;Nb++;body_set_name("Humerus",f,sens,inc0);
}
/* func body_Pelvis */
/* ---------------- */
body_Pelvis(inc0)
{
#include "body_externs()"

	buttock1_g=Buttock1_g+inc0;buttock1_d=Buttock1_d+inc0;
	buttock2_g=Buttock2_g+inc0;buttock2_d=Buttock2_d+inc0;
	pg=poi[1,Nx1]vol(buttock2_g);
	pd=poi[1,Nx1]vol(buttock2_d);
	f=Pelvis+inc0;ny=3;
	body_gen_1(X_Pelvis,Y_Pelvis,Z_Pelvis,f,0,Nx2,ny);
	p=arc(1,0,2*PI*(Nx2-1)/Nx2,Nx2);
	rotx(.5*PI)var("p");
	p*=.5*X_Pelvis,1,.2*Z_Pelvis;
	w4=vertex secy(4)vol(f);
	dila(1.1,1,.6)vertex(w4)vol(f);
	tran(.15*X_Pelvis)vertex(w4)vol(f);
	Belt=poi(w4)vol(f);
/* secy1 */
/* ----- */
	w1=vertex secy(1)vol(f);
	dila(.2,1,.1)vertex(w1)vol(f);
	tran(.2*R_Leg,-.33*Y_Pelvis/ny,0)vertex(w1)vol(f);
	d=.25*R_Leg;
	tran(-.5*d,-.5*d,0)vertex(w1[1],w1[Nx1-1])vol(f);
	tran(-d,-d,0)vertex(w1[0])vol(f);
	v1=CG vertex(w1)vol(f);

/* secy2 */
/* ----- */
	w2=vertex secy(2)vol(f);
	tran(-.05*R_Leg,0,0)vertex(w2[0])vol(f);
	tran(.15*R_Leg,0,0)vertex(w2[Nx1])vol(f);
	dila(.9,1,.7)vertex(w2)vol(f);
	dilx(.6)vertex(w2[0])vol(f);
	dilx(.75)vertex(w2[1],w2[11])vol(f);
dila(1.15)vertex(w2)vol(f);
tran(.05*R_Leg,0,0)vertex(w2)vol(f);
	rota(.5*Ang_Pelvis)vertex(w2)vol(f);
	body_pelvis_1(f,w2,.5,.5,.8,1);

/* secy3 */
/* ----- */
	w3=vertex secy(3)vol(f);
//	dila(.8,1,.65)vertex(w3)vol(f);
	dila(.9,1,.65)vertex(w3)vol(f);
	rota(.5*Ang_Pelvis)vertex(w3)vol(f);
	body_pelvis_1(f,w3,.75,.6,.8,1);

/* secy4 */
/* ----- */
	tran(-.1*R_Leg,0,0)vertex(w4[0])vol(f);
	body_pelvis_1(f,w4,1,.8,.9,1);
	dilx(1.2)vertex(w4[Nx1])vol(f);
	v2=CG vertex(w4)vol(f);
//	np=NP vol(f);poi(0)vol(f)=v1,v2;
//	dila(.75,1,.95)vertex(w4)vol(f);
	dila(.8,1,.95)vertex(w4)vol(f);


/* top skin leg */
/* ------------ */
	np1=NP vol(f);
//dx=.5*R_Leg;dy=-.5*Y_Pelvis;dz=.75*R_Leg;
dx=.25*R_Leg;dy=-.5*Y_Pelvis;dz=.5*R_Leg;
//	d=.5,1,1;
	d=1,1,1;
	poi(0)vol(f)=d*(poi vol(buttock1_g))+(dx,dy,dz);
	np2=NP vol(f);Bod_Leg_g=[np1+1,np2];
	poi(0)vol(f)=d*(poi vol(buttock1_d))+(dx,dy,-dz);
	Num,=f;Nb++;body_set_name("Pelvis",f,0,inc0);

	np3=NP vol(f);Bod_Leg_d=[np2+1,np3];
}
body_pelvis_1(f,w,k,k1,k2,k3)
{
extern Belt,Nx1,Ang_Pelvis;

	a0=a1=k*PI/6;a2=0;dan=(a2-a1)/5;g=CG(Belt);
	for(i=1,5)
	{
		roty(a1)vertex(w[i])vol(f)poi(g);a1+=dan;
	}
	a1=-a0;a2=0;dan=(a2-a1)/5;
	for(i=11,7,-1)
	{
		roty(a1)vertex(w[i])vol(f)poi(g);a1+=dan;
	}
	dila(k1,1,.8)vertex(w[Nx1])vol(f);
	dila(k2,1,.8)vertex(w[Nx1-1,Nx1+1])vol(f);
	rotz(k*Ang_Pelvis)vertex(w)vol(f);
dily(1.5)
}

body_Collarbone(inc,sens,inc0)
{
#include "body_externs()"

	inc=inc*Inc+inc0;f=Collarbone_g+inc;d=.25*R_Arm;
	rev(f)secx(3)poi(1,1,0, 1,.33,0, 1,-.33,0, 1,-1,0);
	rotz(-.5*PI)vol(f);roty(-.5*sens*PI)vol(f);

//	dila(.8*d,.8*d,.6*Z_Spine)vol(f);
	dila(.8*d,.8*d,.5*Z_Spine)vol(f);

	w=vertex secy(3,4)vol(f);roty(.1*sens*PI)vertex(w)vol(f);
	roty(.033*sens*PI)vol(f);

	Num,=f;Nb++;body_set_name("Collarbone",f,sens,inc0);
}

body_Tendon(inc,sens,inc0)
{
#include "body_externs()"

	inc=inc*Inc+inc0;f=Tendon_g+inc;
	vol(f)poi(0,0,0, 0,0,0, 0,0,0)fac(1,2,3);

	Num,=f;Nb++;body_set_name("Tendon",f,sens,inc0);
}

body_Blade(inc,sens,inc0)
{
#include "body_externs()"

	inc=inc*Inc+inc0;f=Blade_g+inc;
	rev(f)secx(Nx1)secy(2)poi(0,0,0,0,0,0);
	p=arc(R_Arm,0,2*PI*(Nx1-1)/Nx1,Nx1);
	if(sens>0)rotx(PI)var("p");
	poi[1,Nx1]vol(f)=p;
	poi[Nx1+1,2*Nx1]vol(f)=p+(0,0,-sens*R_Arm);
	roty(-.1*sens*PI)vertex[1,Nx1]vol(f);
	dila(2.65,1.5,1)vol(f);
	
	if(sens>0)
	{
		tran(R_Arm,0,0)vertex(Nx1)vol(f);
		tran(.5*R_Arm,0,0)vertex(2)vol(f);
	}
	else
	{
		tran(.5*R_Arm,0,0)vertex(Nx1)vol(f);
		tran(R_Arm,0,0)vertex(2)vol(f);
	}
	tran(R_Arm,0,0)vertex(4,10)vol(f);

rotz(-.15*PI)vol(f);
	tran(.15*R_Arm,0,0)vertex(.15*Nx1)vol(f);
	Num,=f;Nb++;body_set_name("Blade",f,sens,inc0);
}
body_Wing(inc,sens,inc0)
{
#include "body_externs()"

	sem=inc;
	inc=inc*Inc+inc0;f=Wing_g+inc;
	d=.1*D;nx=2;ny=50;
//	w=Bod_Illum;w[1]=w[1]+.5;w[4]=.5;
w=2,2,.1,.1,.5;
	grid(f)secx(nx)secy(ny)dim(d,d)illum(w)
		col(1,1,1)validate(0);
	behind vol(f)=0;
	field vol(f)=-1;
	w=vertex secy[1,ny+1]vol(f);mass vertex(w)vol(f)=1;

	limit dist secx vol(f)=d,d;
	limit dist secy vol(f)=0,6*d;

	g=CG secy(1)vol(f);tran(-g)vol(f);
	spring vol(f)=Bod_Sti[2],Bod_Vis[2];
}

body_Belly(inc0)
{
#include "body_externs()"

	f=Belly+inc0;pelvis=Pelvis+inc0;
	nyb=secy vol(pelvis);
	w=vertex secy(nyb+1)vol(pelvis);
//	t=body_size((0,1.15,0, 1,1.1,0),(0,1.1,0, 18,1,0,
	t=body_size((0,1,0, 1,1.1,0),(0,1.15,0, 18,1,0,
		100,.8,0),inc0/Inc0);
	p=(.9,0,.85)*t*Belt;

	p=adjust(Nx2)line(p)law(0,0,0, 1,1,0);
	vol(f)poi(p)fac[1,Nx2]col(1,1,1);
	dilx(.6)vertex(Nx1+1)vol(f);
//	dila(.75,.1,.85)vol(f);
	dila(.65,.1,.85)vol(f);

	body_set_name("Belly",f,0,inc0);
}
/* func body_Spine */
/* --------------- */
body_Spine(inc0)
{
#include "body_externs()"

	p=arc(1,0,2*PI*(Nx2-1)/Nx2,Nx2);rotx(.5*PI)var("p");
	p*=X_Spine,1,Z_Spine;
	for(i=0,Nb_Spine-1)
		vol(inc0+Num_Spine[i])poi[1,3*Nx2]fac[1,Nx2]
			name("Thorax",string(i+1));
	belly=Belly+inc0;f1=Thorax1+inc0;f2=Thorax2+inc0;
	f3=Thorax3+inc0;f4=Thorax4+inc0;
	neck=Neck+inc0;
	n=secy vol(belly);wv=vertex secy(n+1)vol(belly);
	pb1=(1.3,0,1)*Belt;rotz(-.25*Ang_Pelvis)var("pb1");

/* Thorax1 */
/* ------- */
	w1=[1,Nx2];poi(w1)vol(f1)=(1.1,1,1)*pb1;
	w0=[5,9];
	dilx(.7)vertex(w0)vol(f1);
	dilx(.65)vertex(w1[Nx1])vol(f1);
	x=-.1*X_Spine;y=-.1*Y_Spine;
	tran(x,0,0)vertex(1,Nx2)vol(f1);
	tran(0,y,0)vertex(1)vol(f1);

tran(0,-.5*y,0)vertex(2,Nx2-1)vol(f1);
tran(0,.5*y,0)vertex(4,Nx2-3)vol(f1);

	tran(0,.33*y,0)vertex(2,Nx2)vol(f1);
	tran(.15*X_Spine)vertex(Nx1)vol(f2);
	dila(.85,1,.9)vol(f1);
	dilx(.8)vol(f2);
	rotz(.5*Ang_Pelvis)vol(f1);body_Thorax(f1,w1);
	Num,=f1;Nb++;body_set_name("Thorax1",f1,0,inc0);

/* Thorax2 */
/* ------- */
	poi(w1)vol(f2)=(.9,1,1)*pb1;body_Thorax(f2,w1);
	dilz(.5)vertex(Nx1,Nx1+2)vol(f2);
	rotz(-.25*Ang_Pelvis)vol(f2);
	tran(2*R_Arm)vertex(4)vol(f2);
	tran(R_Arm)vertex(3,11)vol(f2);
//dila(1,1,1.1)vol(f2);
	Num,=f2;Nb++;body_set_name("Thorax2",f2,0,inc0);

/* Thorax3 */
/* ------- */
	poi(w1)vol(f3)=(.9,1,1)*pb1;body_Thorax(f3,w1);


dup poi vol(f3);



	dilz(.5)vertex(Nx1,Nx1+2)vol(f3);
/*
	c=body_size((0,1.115,0, 1,.7,0),
		(0,0,0, 12,0,0, 18,1,0, 30,1,0, 100,0,0),inc0);
	tran(c*R_Arm)vertex(4,10)vol(f3);
*/
/* Breast */
/* ------ */
//	t=Body_Breast[inc0/Inc0];

t=.25*Body_Breast[inc0/Inc0];

	dx=t*X_Spine;
	tran(dx,0,0)vertex(2,Nx2)vol(f3);
	tran(1.5*dx,0,0)vertex(3,Nx2-1)vol(f3);

	rotz(-.25*Ang_Pelvis)vol(f3);
	Num,=f3;Nb++;body_set_name("Thorax3",f3,0,inc0);

/* Thorax4 */
/* ------- */
	k=1,1,1.3;x=.2*X_Spine;p1=k*pb1;
	poi(w1)vol(f4)=p1;
	dilx(.8)vertex(w0)vol(f4);
	dila(1,1,.7)vol(f4);
	dilx(.8)vertex(1)vol(f4);
	dilx(.9)vol(f4);
	rotz(-.5*Ang_Pelvis)vol(f4);
	body_Thorax(f4,w1);

	Num,=f4;Nb++;body_set_name("Thorax4",f4,0,inc0);

	dila(.9,1,1)vol(f1,f2,f3,f4);	/*???*/

/* Neck */
/* ---- */
	poi(w1)vol(neck)=(.55,1,.4)*pb1;
	dilx(.4)vertex(1)vol(neck);
	dila(.7,1,1.125)vertex(2,12)vol(neck);
	dilz(1.125)vertex(3,4,10,11)vol(neck);
	dilx(.8,1,.5)vertex(1)vol(neck);
	dilx(1.2)vertex(11,12)vol(neck);
	hom(1.5)vertex(5,9)vol(neck);
	dila(.9,1,.85)vol(neck);
	body_set_name("Neck",neck,0,inc0);

/* correct rota */
/* ------------ */
	a1=.05*PI;a2=.1*PI;f=belly,f1,f2,f3,f4;n=dim(f);da=(a2-a1)/n;
	for(i=0,n-1)
	{
		fi=f[i];rotz(a1)vol(fi);a1+=da;
	}

	Num,=neck;Nb++;
}
body_Thorax(f2,w1)
{
extern Nx1;

	dilx(.7)vertex(w1[Nx1])vol(f2);
}

body_Head(inc0)
{
#include "body_externs()"

	f=Head+inc0;Secy_Head=ny0=12;
	p=arc(1,.5*PI,-PI,ny0+1);p=R_Head*(.8,1,.6)*p{2,ny0};
	rev(f)secx(Nx2)poi(p);
//		dila(1,1,.8)vol(f);

	Num,=f;Nb++;body_set_name("Head",f,0,inc0);

	limit rotx vol(f)=-.25*PI,.25*PI;
	limit roty vol(f)=-.25*PI,.25*PI;
	limit rotz vol(f)=-.25*PI,.5*PI;

	ny=9;wf=wf2=NIL;
	for(i=1,ny+1)
	{
		w=vertex secy(i)vol(f);wf,=w[9,11],w[0,3];
		wf2,=w[1,11];
	}
	w=vertex secy(1)vol(f);
	dila(1.2,1.1,1)vertex(w)vol(f);

	w=vertex secy(2)vol(f);g=vertex(w[2],w[9])vol(f);
	dila(1.2,1,1)vertex(w[0,2],w[9,11])poi(g)vol(f);

	w=vertex secy(2)vol(f);g=vertex(w[2],w[9])vol(f);
	dila(1.5,1,1)vertex(w[0,2],w[9,11])poi(g)vol(f);

	w=vertex secy(3)vol(f);
	dila(1,1,.75)vertex(w)vol(f);

	w=vertex secy(4)vol(f);g=vertex(w[2],w[9])vol(f);
	dila(1.15,1,.9)vertex(w[0,3],w[8,11])poi(g)vol(f);

/* chin */
	nx2=2*Nx1;w2=vertex secy(2)vol(f);
	w=w2[0,.25*nx2],w2[.75*nx2,nx2-1];
	rotz(.075*PI)vertex(w)vol(f);
	dila(1,1,.8)vertex(w)vol(f);
	w3=vertex secy(3)vol(f);
	w=w3[0,.25*nx2],w3[.75*nx2,nx2-1];
	rotz(.035*PI)vertex(w)vol(f);
	dila(1,1,.9)vertex(w)vol(f);
/* mouth */
	w=vertex secy(3)vol(f);
	dila(1.1,1,.9)vertex(w[0,1],w[10,11])vol(f);
/* noze */
	w=vertex secy(4)vol(f);
	dila(.95,1,1)vertex(w[0])vol(f);
	w=vertex secy(5)vol(f);
	w5=vertex secy(5)vol(f);
	dila(1.3,1,1)vertex(w[0])vol(f);
	tran(0,.15*R_Head,0)vertex(w[0])vol(f);
	dila(1,1,.6)vertex(w[1],w[11])vol(f);
/* eyes */
	w=vertex secy(6)vol(f);
	tran(0,.1*R_Head,0)vertex(w)vol(f);
	dila(1,1,.5)vertex(w[1],w[11])vol(f);
	
	w=vertex secy(7)vol(f);g=vertex(w[2],w[9])vol(f);
	dila(1.15,1,1.1)vertex(w[0,3],w[8,11])poi(g)vol(f);

	w=vertex secy(8)vol(f);g=vertex(w[2],w[9])vol(f);
	dila(1.2,1,1.2)vertex(w[0,3],w[8,11])poi(g)vol(f);

	w=vertex secy(9)vol(f);g=vertex(w[2],w[9])vol(f);
	w=vertex secy[ny-6,ny+1]vol(f);
	dila(1.3,1,1.3)vertex(w[0,3],w[8,11])poi(g)vol(f);

	dila(1.25,1.2,1)vol(f);ny0=secy vol(f);
	w=vertex secy[ny0-6,ny0+1]vol(f);
	dila(1,C_Y,1)vertex(w)vol(f);
/* Face */
	body_Face(inc0,f,ny,wf);
/* Hair */
	body_Hair(f,inc0);
}
/* func body_Hair */
/* -------------- */
body_Hair(f,inc0)
{
extern Nx2,Hair,Secy_Head,D,Num,Nb,K_Hair,Inc0;
extern Bod_Sti_Hair,Bod_Vis_Hair,R_Head;

	d=.3*D;
	nyh=secy vol(f);k=K_Hair[inc0/Inc0];
	nx=Nx2-2;ny1=nyh-1;ny2=int(ny1+k);
	f0=Hair+inc0;
	p=arc(1.25,-.5*PI,.75*PI,ny2+1);
	rev(f0)ang(-2*PI)secx(nx)poi(p)close(0)illum(2,1,.1,.1,0)
		col(0,0,0);
	dila(R_Head*(1.3,2,1.2))vol(f0);
	a=.5;
	w=vertex secx(1,2)vol(f0);dila(a,a,a)vertex(w)vol(f0);
	w=vertex secx(Nx2-2,Nx2-1)vol(f0);dila(a,a,a)vertex(w)vol(f0);
	w=fac secx(nx)vol(f0);
	validate fac(w[5,ny2-1])vol(f0)=0;
	w=fac secx(1)vol(f0);validate fac(w[5,ny2-1])vol(f0)=0;
	x1=0;x2=-R_Head;dy=ny2-ny1;
	if(dy>=1)
		dx=(x2-x1)/dy;
	else
	{
		dx=0;dy=1;
	}
	for(i=ny1,ny2+1)
	{
		c=1+5*(i-ny1)/dy;
		w=vertex secy(i)vol(f0);
		dila(c,1,c)vertex(w)vol(f0);
		tran(x1,0,0)vertex(w)vol(f0);x1+=dx;
	}
/*
	w=vertex secy[ny1+1,ny2+1]vol(f0);
	w,=vertex secyx(2,3)vol(f0);
	w,=vertex secyx(Nx2-3,Nx2-2)vol(f0);
	mass vertex(w)vol(f0)=1;
*/
	for(i=1,Nx2-1)
	{
		w=vertex secx(i)vol(f0);
		mass vertex(w[ny1,ny2])vol(f0)=1;
	}
//	np=NP vol(f0);mass vertex[1,np]vol(f0)=1;
	spring vol(f0)=Bod_Sti_Hair[2],Bod_Vis_Hair[2];

	d=6*R_Head/Nx2;
	limit dist secx vol(f0)=0,d;
//	limit dist secy vol(f0)=0,d;

	Num,=f0;Nb++;body_set_name("Hair",f0,0,inc0);
}
body_Robe(inc0)
{
#include "body_externs()"

	f=Robe+inc0;t4=Thorax4+inc0;
	ny=nx=14;p0=adjust(nx+1)line(-D,0,0,D,0,0);d=5*D/ny;
	grid(f)secx(nx)secy(ny)illum(2,1,.1,.1,.5)dim(d)
validate(0);
	spring vol(f)=Bod_Sti[2],Bod_Vis[2];
	roty(-.5*PI)vol(f);
	tran(-D,-2*D,0)vol(f);
	anc abs vol(f)=1;
	v=vertex secy[2,ny+1]vol(f);mass vertex(v)vol(f)=1;
	spring vol(f)=Bod_Sti[2],Bod_Vis[2];
	d=.125*D;
	generate speed vertex vol f;
d=12;	/*???*/
	limit dist secx vol(f)=0,5*d;
//	limit dist secy vol(f)=.5*d,1.5*d;
}

/* func body_force_Hair */
/* -------------------- */
body_force_Hair(hair,thorax);
{
return;
extern D,Bod_Coe_Hair;

	nyh=secy vol(hair);c=Bod_Coe_Hair[2];d=D;
	w=vertex secy[nyh-3,nyh+1]vol(hair);n=dim(w);
	g=CG matrix vol(thorax4);generate poi anc vol(hair);
	for(i=0,n-1)
	{
		s=w[i];p=poi(s)anc vol(hair);
		if(dist(p,g)<d)
		{
			ff=c*unit(p-g);
			force add vertex(s)vol(hair)=ff,0;
		}
	}
}

/* func body_Face */
/* -------------- */
body_Face(inc0,f,ny,wf)
{
extern Face,Nx1,Image_Face,Head_Ax,Num,Nb;

	f2=Face+inc0;
	grid(f2)secx(Nx1)secy(ny)col(2,1.5,1);np=NP vol(f2);
	for(i=1,np)poi(i)vol(f2)=poi(wf[i-1])vol(f);
	np=NP vol(f);poi(0)vol(f)=0,0,0,0,1,0;
	hom(1.1)matrix vol(f2);
	dila(1.3,1.1,1.2)matrix vol(f2);
//   texture vol(f2)=Image_Face;
	Head_Ax=np+1,np+2;
	Num,=f2;Nb++;body_set_name("Face",f2,0,inc0);
	body_set_name("Face",f2,0,inc0);
}

body_Sex(inc1)
{
#include "body_externs()"

	inc0=inc1*Inc0;
	f0=Sex0+inc0;f1=Sex1+inc0;f2=Sex2+inc0;pelvis=Pelvis+inc0;
	d=R_Sex;d2=2*d;d3=.75*d;

	rev(f0)secx(Nx1)poi(d2,d2,0, d2,-d2,0);rotz(.5*PI)vol(f0);
	p=poi([1,3],[9,11])vol(pelvis);g=CG(p);
	poi([1,Nx1])vol(f0)=p-g;
	dily(.25)vertex(7)vol(f0);tran(0,d,0)vertex[1,Nx1]vol(f0);
	tran(1.5*R_Sex,3.5*R_Sex,0)vertex[Nx1+1,Nx2]vol(f0);

	rev(f1)secx(Nx1)poi(d,d,0,d,-d,0);rotz(.5*PI)vol(f1);

	rev(f2)secx(Nx1)poi(d,d3,0, .85*d,-.75*d3,0, 0,-d3,0);
	rotz(.5*PI)vol(f2);
	dila(1,1.25,1.2)vertex[1,Nx1]vol(f2);
	rotz(-.1*PI)vertex[1,Nx1]vol(f2);
	dila(1.1,1.2,1.15)vertex[Nx1+1,2*Nx1]vol(f2);

	body_limit_rota(f1, -.3*PI,.4*PI, (0,-.2,1),(1,.2,1));

	body_meta(inc1,0);
}

body_meta(inc1,num)
{
#include "body_externs()"

	inc0=inc1*Inc0;
	if(Sex[inc1])
	{
		meta(num)roty rota rota vol(Sex1+inc0)=Femur_g+inc0,-.5,Femur_d+inc0,.5;
		meta(num)rotx rota rota vol(Sex1+inc0)=Femur_g+inc0,.5,Femur_d+inc0,-.5;
	}
	meta(num)rota rota rota vol(Thorax2+inc0)=Thorax1+inc0,.5,Thorax3+inc0,.5;
	meta(num)rota rota rota vol(Neck+inc0)=Thorax4+inc0,.5,Head+inc0,.5;
}

body_Erec(inc1)
{
#include "body_externs()"

	if(inc1>=(Nb_Body[2]))return;
	if(Sex[inc1]<.5)return;
	c=body_size((0,0,0, 1,1,0),(0,.2,0, 12,.5,0, 18,1,0, 100,1,0),inc1);
	k=c*Erec[inc1];
	inc0=inc1*Inc0;f0=Sex0+inc0;f1=Sex1+inc0;f2=Sex2+inc0;
	kx=1+.75*k;kyz=1+.6*k;
	dila(1.1,kyz,kyz)matrix vol(f0);
	dila(kx,1,1)matrix vol(f1);
	an=limit rota vol(f1);a0=an[0];a1=an[1];
	an=a1+k*(a0-a1);rota(an)matrix vol(f1);
	rota(.5*an)matrix vol(f2);
}
/* func body_Dila_Erec */
/* ------------------- */
body_Dila_Erec(inc0,k)
{
extern Sex0,Sex1,Sex2,Inc0;

	dila(1+k*(.5,1,.5))matrix vol((Sex0,Sex1,Sex2)+inc0*Inc0);
}
body_cor(inc0)
{
extern Inc;

	body_cor_hum(inc0,0);body_cor_hum(inc0,Inc);
}
body_cor_hum(inc0,inc)
{
#include "body_externs()"

	hum=Humerus_g+inc0+inc;th2=Thorax2+inc0;
	if(inc)
	{
		w=vertex secx(2)vol(hum);n=11;
	}
	else
	{
		w=vertex secx(6)vol(hum);n=2;
	}
	attach(0)vertex(w[0])vol(hum)vertex(n)vol(th2);
}

/* SKIN */
/* ==== */

body_Skin(inc1)
{
#include "body_externs()"

	inc0=inc1*Inc0;
	if(validate vol(Pelvis+inc0)==NIL)return;

//	body_Skin_Spine(inc0);

	body_Skin_Leg(0,1,inc0);body_Skin_Leg(1,-1,inc0);
	body_Skirt(inc1,inc0);
//	body_Robe(inc0);body_Hat(inc1,inc0);
	body_Skin_Arm(0,1,inc0);body_Skin_Arm(1,-1,inc0);
	body_Skin_Finger(0,1,inc0);
	body_Skin_Finger(1,-1,inc0);

	body_Skin_Spine(inc0);

	body_Skin_Sex(inc0);

	bod_Illum=Bod_Illum+(0,.5,0,.3,0);



//	illum vol((Skin,Wing,Face)+inc0)=bod_Illum;
	illum vol((Skin,Wing_g,Wing_d,Face)+inc0)=bod_Illum;

	skin=Skin+inc0;face=Face+inc0;
	col vol(skin,face)=Col_Skin{inc1};
	ext vol(skin)=Ext_Skin;
	ext vol(Skin_Spine+inc0)=Ext_Skin_Spine;
	behind vol(skin,face)=-1;	
	body_validate_spine(inc1,0);
}
body_generate_normal()
{
extern Nb_Body,Skin,Inc0;

	nb=Nb_Body[2];skin=Skin;n=dim(skin);
	for(i=1,nb)
	{
		for(j=0,n-1)
		{
			s=skin[j];
			attach(0)generate normal fac vol(s);
			attach(0)generate normal vertex vol(s);
		}
		skin+=Inc0;
	}
}
body_generate_normal_vertex()
{
extern Nb_Body,Skin_Spine;

	nb=Nb_Body[2];skin=Skin_Spine;
	for(i=0,nb-1)body_attach_spine(i);
}
body_generate_ext()
{
extern Nb_Body,Skin,Inc0;

	nb=Nb_Body[2];skin=Skin;n=dim(skin);
	for(i=1,nb)
	{
		for(j=0,n-1)
			attach(0)generate ext vol(skin[j]);
		skin+=Inc0;
	}
}

body_Skin_Leg(inc,sens,inc0)
{
#include "body_externs()"

	inc=inc*Inc+inc0;f=Skin_Leg_g+inc;
	pelvis=Pelvis+inc0;belly=Belly+inc0;femur=Femur_g+inc;
	v=(Toe_g,Foot_g,Tibia_g,Femur_g)+inc;
	buttock1=Buttock1_g+inc;buttock2=Buttock2_g+inc;
	w_butt=[1,Nx1];w4=vertex secy(4)vol(pelvis);
	if(sens>0)
		w_pelv=Bod_Leg_g;
	else
w_pelv=Bod_Leg_d;
	ny=secy vol(pelvis);wp=vertex secy(ny+1)vol(pelvis);
	g=CG secy(ny+1)vol(pelvis);poi(0)vol(pelvis)=g;
	np=NP vol(pelvis);
	if(sens>0)
		wp=wp[7,11];
	else
		wp=wp[6,11];
	g=CG vol(belly);poi(0)vol(belly)=g;np=NP vol(belly);
	if(sens>0)
		wb=8,12;
	else
		wb=2,6;
	wb,=np;
	vol(f)envelope(v)secx(Nx1)
		meta(buttock1,w_butt)
		meta(buttock2,w_butt)
		meta(pelvis,w_pelv);
	body_set_name("Skin_Leg",f,sens,inc0);
}
/* func body_Skirt */
/* --------------- */
body_Skirt(inc1,inc0)
{
#include "body_externs()"

	pel=Pelvis+inc0;f1=Skirt[0]+inc0;f2=f1+1;belly=Belly+inc0;
	ny=secy vol(pel);ny0=8*ny;w=vertex secy(ny+1)vol(pel);
	Skirt1=[1,Nx1];Skirt2=[Nx2,Nx1+1];
	d=.5*D/ny0;
	grid(f1)secx(Nx1-1)secy(ny0)dim(d)validate(0)					col(1,1,1)illum(Bod_Illum)behind(1);
	//texture vol(f1)=1;
	dup vol(f1,f2);
	roty(.5*PI)vol(f1);roty(-.5*PI)vol(f2);
	c1=1;c2=5;dc=(c2-c1)/ny0;
	p1=poi(Skirt1)vol(belly);p2=poi(Skirt2)vol(belly);
	for(i=1,ny0+1)
	{
		p=c1*p1;
		w=vertex secy(i)vol(f1);
		poi(w)vol(f1)=p;p1+=0,d,0;
		w=vertex secy(i)vol(f2);
		poi(w)vol(f2)=p2;p2+=0,d,0;c1+=dc;
	}
	generate mass vertex vol(f1,f2);
	mass vertex[1,Nx2]vol(f1,f2)=0;
	spring vol(f1,f2)=Bod_Sti[2],Bod_Vis[2];
//	attach(0)vertex[1,Nx2]vol(f0)vertex(w)vol(pel);
//	attach(0)poi(w)vol(f0)pod(w)anc vol(pel);
	limit dist secx vol(f1,f2)=0,6*d;
	limit dist secy vol(f1,f2)=1.5*d,3*d;
	Num,=f1;Nb++;body_set_name("Skirt",f1,1,inc1);
	Num,=f2;Nb++;body_set_name("Skirt",f2,-1,inc1);
}
/* func body_Hat */
/* ------------- */
body_Hat(inc1,inc0)
{
#include "body_externs()"

	f=Head+inc0;f0=Hat+inc0;dup vol(f,f0);
	x=1.25*D;x1=.33*x;ny=secy vol(f0);ny2=5;y=x1;y=10;
	p=.15*x,y,0;
	p,=.2*x,y,0;
	p,=.9*x,y,0;
	p,=x,y,0;
	p,=x,0,0;
	p,=.9*x,0,0;
	p,=x1,.75*y,0;
	p,=x1,1.5*y,0;
	p,=0,2.75*y,0;np=NP(p);
	rev(f0)ang(2*PI)secx(Nx2)poi(p)illum(2,1,.1,.1,0)
		validate(0);
	ny0=secy vol(f0);
//	spring vol(f0)=Bod_Sti[2],Bod_Vis[2];
	w=vertex secy[1,6]vol(f0);mass vertex(w)vol(f0)=1;
	w=vertex secy[7,ny0+1]vol(f0);mass vertex(w)vol(f0)=0;
mass vol(f0)=0;
//	limit dist secx vol(f0)=0,.25*D;
	
		w=vertex secy(ny-3)vol(f);
		w0=vertex secy(5)vol(f0);
		poi(w0)vol(f0)=(1.1,1,1.1)*(poi(w)vol(f));

		w=vertex secy(ny-2)vol(f);
		w0=vertex secy(5)vol(f0);
		poi(w0)vol(f0)=(1.1,1,1.1)*(poi(w)vol(f));

		w=vertex secy(ny-1)vol(f);
		w0=vertex secy(6)vol(f0);
		poi(w0)vol(f0)=(1.1,1,1.1)*(poi(w)vol(f));

		w=vertex secy(ny)vol(f);
		w0=vertex secy(7)vol(f0);
		poi(w0)vol(f0)=(1.1,1,1.1)*(poi(w)vol(f));

	lead(f)poi(0,0,0)follow(f0)poi(0,0,0);
	
	Num,=f0;Nb++;body_set_name("Hat",f0,0,inc1);
}

body_Skin_Spine(inc0)
{
#include "body_externs()"

	f=Skin_Spine+inc0;
	pelvis=Pelvis+inc0;belly=Belly+inc0;
	thorax1=Thorax1+inc0;thorax2=Thorax2+inc0;
	thorax3=Thorax3+inc0;thorax4=Thorax4+inc0;
	buttock1_g=Buttock1_g+inc0;buttock1_d=Buttock1_d+inc0;
	buttock2_g=Buttock2_g+inc0;buttock2_d=Buttock2_d+inc0;
	femur_g=Femur_g+inc0;femur_d=Femur_d+inc0;
	humerus_g=Humerus_g+inc0;
	humerus_d=Humerus_d+inc0;
	tendon_g=Tendon_g+inc0;tendon_d=Tendon_d+inc0;
	nyh=secy vol(humerus_g);
	wh=vertex secy(nyh+1)vol(humerus_g);
	neck=Neck+inc0;head=Head+inc0;
	coll_g=Collarbone_g+inc0;coll_d=Collarbone_d+inc0;
	blade_g=Blade_g+inc0;blade_d=Blade_d+inc0;
	ny=secy vol(pelvis);

	wb1_g=[1,5];wb1_d=[1,5];
	wb2_g=[1,6];wb2_d=[1,5];

/* envelope */
/* -------- */
	w=[1,Nx2];
	vol(f)envelope close secx(Nx2)
		envelope(pelvis)	/* secy[1,4] */
		meta(belly,w)	/* secy 5 */
		meta(thorax1,w)	/* secy 6 */
		meta(thorax2,w)	/* secy 7 */
		meta(thorax3,w)	/* secy 8 */
		meta(thorax4,w)	/* secy 9 */
		meta(neck,w)	/* secy 10 */
		envelope(head);	/* secy [11,22] */
/* corrections */
/* ----------- */

	w1=vertex secy(1)vol(pelvis);
	w2=vertex secy(2)vol(pelvis);
	w3=vertex secy(ny)vol(pelvis);
	w4=vertex secy(ny+1)vol(pelvis);
	w8=vertex secy(8)vol(f);
	w9=vertex secy(9)vol(f);w10=vertex secy(10)vol(f);

/* Buttocks */

	envelope(0)adjust vol(f)=buttock1_g,[2,5],w1[2,5];
	envelope(0)adjust vol(f)=buttock1_d,[3,6],w1[7,10];

/*
	envelope(0)adjust vol(f)=buttock2_g,[2,5],w2[2,5];
	envelope(0)adjust vol(f)=buttock2_d,[3,6],w2[7,10];
*/

/*
	envelope(0)adjust vol(f)=buttock2_g,[2,5],w3[2,5];
	envelope(0)adjust vol(f)=buttock2_d,[3,6],w3[7,10];
*/

/* Collarbone */
	wc=vertex secx(1)vol(coll_g);
	envelope(0)adjust vol(f)=coll_g,wc[0,3],w9[0,3];
	wc=vertex secx(1)vol(coll_d);
	envelope(0)adjust vol(f)=coll_d,wc[3,1],w9[9,11];
/* Blade */


	w5=vertex secx(5)vol(f);
	envelope(0)adjust vol(f)=blade_g,5,4,3,w5[6,8];
	w6=vertex secx(6)vol(f);
	envelope(0)adjust vol(f)=blade_g,11,10,9,w6[6,8];
	w8=vertex secx(8)vol(f);
	envelope(0)adjust vol(f)=blade_d,9,10,11,w8[6,8];
	w9=vertex secx(9)vol(f);
	envelope(0)adjust vol(f)=blade_d,3,4,5,w9[6,8];


/*
w=vertex secy(8)vol(f);s1=w[Nx1-1];
attach(0)vertex(s1)vol(f)vertex(Nx1)vol(thorax4);
*/
/* Tendon */
	head=Head+inc0;w10=vertex secy(10)vol(f);
/*
	attach_tendon(tendon_g,3,head,coll_g);
	attach_tendon(tendon_d,10,head,coll_d);
*/

	attach_tendon(tendon_g,4,head,coll_g);
	attach_tendon(tendon_d,9,head,coll_d);
	envelope(0)adjust vol(f)=tendon_g,2,w10[1];
	envelope(0)adjust vol(f)=tendon_d,2,w10[11];
next:
	body_set_name("Skin_Spine",f,0,inc0);
}
attach_tendon(tendon,h,head,coll)
{
	attach(0)vertex(1)vol(tendon)vertex(h)vol(head)abs;
	attach(0)vertex(3)vol(tendon)vertex(1)vol(coll)abs;
	attach(0)vertex(2)vol(tendon)vertex(1)vol(tendon)
		vertex(3)vol(tendon)abs;
}

body_Skin_Sex(inc0)
{
#include "body_externs()"

	f=Skin_Sex+inc0;pel=Pelvis+inc0;
	f0=Sex0+inc0;f1=Sex1+inc0;f2=Sex2+inc0;nx=secx vol(f1);
	p=arc(.1*X_Pelvis,0,2*PI,nx);roty(.5*PI)var("p");
	p+=CG secy(1)vol(pel);np0=NP vol(pel);poi(0)vol(pel)=p;
	vol(f)envelope close(1)secx(nx)
		meta(pel,[np0+1,np0+nx])
		envelope(f0,f1,f2);
	
	body_set_name("Skin_Sex",f,0,inc0);
}

body_Skin_Arm(inc,sens,inc0)
{
#include "body_externs()"

	inc=inc*Inc+inc0;f=Skin_Arm_g+inc;blade=Blade_g+inc;
	thorax2=Thorax2+inc0;thorax4=Thorax4+inc0;
//	v=(Hand_g,Radius_g,Humerus_g,Blade_g)+inc;
	v=(Hand_g,Radius_g,Humerus_g)+inc;
	blade=Blade_g+inc;w=vertex secy(1)vol(blade);
	vol(f)envelope secx(Nx1)
		envelope(v)
		meta(blade,w);
goto bid;
/* corrections */
	ny=secy vol(f);w1=vertex secy(ny+1)vol(f);
	if(sens>0)
	{
		s1=5;s2=2;
	}
	else
	{
		s1=D1;s2=D2;
	}
	attach(0)vertex(w1[s1])vol(f)vertex(s2)vol(thorax2);
//goto bid;


	r=.75*R_Arm;
	x=.25*X_Spine;y=0;np=NP vol(blade);
	p=arc(R_Arm,0,-2*PI*(Nx1-1)/Nx1,Nx1);
	rotx(-PI/2)var("p");	/* base blade */
	rotx(-.7*sens*PI+PI)var("p");
	p*=2,2,1;
/* Thorax */
	ny=secy vol(f);
//goto bid;
//	th2=Thorax2+inc0;
th3=Thorax3+inc0;dny3=ny-2,ny;
	if(sens>0)
	{
		vt=[3,1];
		w=vertex secx(1)vol(f);
		va=w[dny3];attach(0)vertex(va)vol(f)vertex(vt)
			vol(th3)abs;
	}
	else
	{
		vt=[11,12],1;
		w=vertex secx(1)vol(f);
		va=w[dny3];attach(0)vertex(va)vol(f)vertex(vt)
			vol(th3)abs;
	}
/* Collarbone */
	if(sens>0)
		x2=2;
	else
		x2=6;
	collarbone=Collarbone_g+inc;
	x1=vertex secx(1)vol(collarbone);
	x2=vertex secx(x2)vol(f);
	attach(0)vertex(x2[ny,ny-3])vol(f)vertex(x1[0,3])
		vol(collarbone)abs;
/* Blade */
/*
r=.25*R_Arm;
	tran(-.25*r)vertex(3,9)vol(blade);
	tran(.25*r)vertex(4,10)vol(blade);
	tran(-r*(1,1))vertex(2)vol(blade);
//rotz(-.25*PI)vol(f);
*/
bid:
	body_set_name("Skin_Arm",f,sens,inc0);
}

body_Skin_Finger(inc,sens,inc0)
{
#include "body_externs()"

	inc=inc*Inc+inc0;f0=Skin_Finger_g+inc;
	f=Finger_g+inc;nx=secx vol(f);v=[f+2,f]+12;
	for(i=1,5)
	{
		vol(f0)envelope(v)secx(nx);v-=3;f0++;
		body_set_name("Skin_Finger",f0,sens,i,inc0);
	}
}

body_validate_spine(inc0,v)
{
return;
#include "body_externs()"

	inc0*=Inc0;skin_spine=Skin_Spine+inc0;
	body_validate_arm(inc0,v);
	body_validate_leg(inc0,v);

	f=Skin_Spine+inc0;k=1;
	for(i=1,2)
	{
		w=fac secy(i)vol(skin_spine);
	//	validate fac(w)vol(skin_spine)=-1;
		validate fac(w[1],w[Nx2-1])vol(skin_spine)=-1;

		w=fac secy(k,k)ext vol(skin_spine);
	//	validate fac(w)ext vol(skin_spine)=-1;
	validate fac(w[1,2],w[2*Nx2-3,2*Nx2-1])vol(skin_spine)=-1;

		w=fac secy(k,k+1)ext vol(skin_spine);k+=2;
	//	validate fac(w)ext vol(skin_spine)=-1;
		validate fac(w[1,2],w[2*Nx2-3,2*Nx2-1])vol(skin_spine)=-1;
	}
return;
/*
	w=fac secy(2)vol(f);nx=secx vol(f);
	validate fac(w[1],w[nx-2])vol(f)=-1;
	nx=secx ext vol(f);
	w=fac secy(3)ext vol(f);
	validate fac(w[3,4],w[nx-2,nx-3])ext vol(f)=-1;
	w=fac secy(4)ext vol(f);
	validate fac(w[3,4],w[nx-5,nx-6])ext vol(f)=-1;
*/

	ny=secy vol(f);
	for(i=-6,-3)
	{
		w=fac secy(ny+i)vol(f);n=dim(w);
		validate fac(w[.75*n,n-1],w[0,.25*n])vol(f)=-1;
	}
	w=fac secy(n-1)vol(skin_spine);n=dim(w);
	validate fac(w[.25*n,.75*n])vol(skin_spine)=-1;
	w=fac secy(2)vol(skin_spine);
	validate fac(w[1,n-2])vol(skin_spine)=-1;
	validate fac(w[.5*n])vol(skin_spine)=1;
k=1;
	ny=secy ext vol(f);n=k*ny;nx=secx ext vol(f);
	w=fac secy(n)ext vol(Skin_Spine);nw=dim(w);
	x1=.3*nw;x2=.7*nw;
	validate fac(w)extvol(Skin_Spine)=-1;
	w=fac secy(n-1)ext vol(Skin_Spine);
	validate fac(w)extvol(Skin_Spine)=-1;

	w=fac secy(n-2)ext vol(Skin_Spine);
	validate fac(w[x1,x2])extvol(Skin_Spine)=-1;
	w=fac secy(n-3)ext vol(Skin_Spine);
	validate fac(w[x1,x2])extvol(Skin_Spine)=-1;
}

body_validate_leg(inc0,v)
{
return;
#include "body_externs()"

	f=Skin_Leg_g+inc0;ny=secy vol(f);

	w=fac secy(ny)vol(f);
	validate fac(w[Nx1-1])vol(f)=v;
	validate fac(w[0])vol(f+Inc)=v;

	w=fac secy(ny)ext vol(f);
	validate fac(w[2*Nx1-2,2*Nx1-1])ext vol(f)=v;
	validate fac(w[0,1])ext vol(f+Inc)=v;
	w=fac secy(ny-1)ext vol(f);
	validate fac(w[2*Nx1-2,2*Nx1-1])ext vol(f)=v;
	validate fac(w[0,1])ext vol(f+Inc)=v;

return;
	validate fac(w[Nx1-1])vol(f)=v;
	validate fac(w[0])vol(f+Inc)=v;
	
	w=fac secy(ny-1)ext vol(f);
	validate fac(w[0,1])ext vol(f)=-1;
	validate fac(w[nx-2,nx-1])ext vol(f+Inc)=-1;

	w=fac secy(ny)ext vol(f);
	validate fac(w[0,1])ext vol(f)=-1;
	validate fac(w[nx-2,nx-1])ext vol(f+Inc)=-1;
}
body_validate_ext_g(f,ny,v,w2)
{
	w=fac secy(ny)ext vol(f);
	w2=get_fac(w,w2);
	validate fac(w2)ext vol(f)=v;
}
body_validate_ext_d(f,ny,v,w2)
{
	w=fac secy(ny)ext vol(f);
	w2=get_fac(w,w2);
	validate fac(w2)ext vol(f)=v;
}
get_fac(w,s)
{
	n=dim(s);w2=calloc(n);
	for(i=0,n-1)w2[i]=w[(s[i])];
	return(w2);
}
body_validate_arm(inc0,v)
{
return;
extern Skin_Arm_g,Skin_Arm_d,Inc;

	f=Skin_Arm_g+inc0;ny=secy vol(f);
	w=fac secy(ny)vol(f);
//	w2=get_fac(w,[1,2]);
	w2=get_fac(w,[1,5]);
	validate fac(w2)vol(f)=0;
//	w2=get_fac(w,[2,3]);
	w2=get_fac(w,[2,7]);
	validate fac(w2)vol(f+Inc)=0;

	ny=secy ext vol(f);
	body_validate_ext_g(f,ny-1,v,[1,4]);
	body_validate_ext_g(f,ny,v,[1,4]);
	body_validate_ext_d(f+Inc,ny-1,v,[2,5]);
	body_validate_ext_d(f+Inc,ny,v,[2,5]);
}

/* func body_meta_sphere */
/* --------------------- */
body_meta_sphere(f,inc0,y1,y2)
{
#include "body_externs()"

//	meta sphere validate vol(f)=1;
	thorax4=Thorax4+inc0;dthorax3=D;
	thorax2=Thorax2+inc0;dthorax2=D;
	w=vertex secy[y1,y2]vol(f);c=Bod_Coe_Hair[2];
	meta sphere force vertex(w)vol(f)=
		thorax4,dthorax4,c,
		thorax2,dthorax2,c;
}

/* Limits */
/* ====== */

body_set_limits(inc0)
{
#include "body_externs()"

	humerus_g=Humerus_g+inc0;humerus_d=Humerus_d+inc0;
	body_limit_rota((Toe_g,Toe_d)+inc0, -.1*PI,.2*PI, (-.2,-.2,1),(.2,.2,1));
	body_limit_rota((Foot_g,Foot_d)+inc0, -.125*PI,.4*PI, (-.2,-.2,1),(.2,.2,1));
	body_limit_rota((Tibia_g,Tibia_d)+inc0, 0,.75*PI, (-.,-.2,1),(.1,.2,1));
//	ax1=unit(-.5,-.25,-.5);ax2=unit(.5,.25,.5);
	ax1=unit(-1,-.5,-1);ax2=unit(1,.5,1);
a1=-.8*PI;a2=.35*PI;
//a1=-PI;a2=.5*PI;
	body_limit_rota(Femur_g+inc0, a1,a2, ax1,ax2);
	body_limit_rota(Femur_d+inc0, a1,a2, ax1,ax2);

limit rota rotz vol((Femur_g,Femur_d)+inc0)=a1,a2;
limit rotx vol((Femur_g)+inc0)=0,.25*PI;
limit rotx vol((Femur_d)+inc0)=-.25*PI,0;

/*
	limit rota vol((Buttock1_g,Buttock1_d)+inc0)=
		limit rota vol(femur_g);
*/
	body_limit_rota(Hand_d+inc0, -.125*PI,.5*PI, (1,0,0),(1,0,0));
	body_limit_rota(Hand_g+inc0, -.5*PI,.125*PI, (1,0,0),(1,0,0));

	body_limit_rota((Finger_g+[0,14])+inc0, -.3*PI,.05*PI, (1,0,0),(1,0,0));
	body_limit_rota((Finger_d+[0,14])+inc0, -.05*PI,.3*PI, (1,0,0),(1,0,0));

	body_limit_rota((Radius_g,Radius_d)+inc0, -.85*PI,0, (0,-.2,1),(0,.2,1));

body_limit_rota(humerus_g,0,.5*PI);
	ax1=unit(-1,-.5,1);ax2=unit(1,.5,1);
body_limit_rota(humerus_d,-.5*PI,0,0);


	nums=Num_Spine_Dynamic+inc0;n=dim(nums);

	a1=-.75*PI/n;a2=1.15*PI/n;
	ax1=unit(-1,-.2,1);ax2=unit(1,.2,1);
	for(i=0,n-2)
	{
		body_limit_rota(nums[i], a1,a2, ax1,ax2);
	}

//body_limit_rota(Head+inc0, -.5*PI,.5*PI, ax1,ax2);

	body_limit_rota(Head+inc0, -.33*PI,.33*PI, ax1,ax2);

	limit rota vol(Collarbone_g+Inc0)=0,.25*PI;
	limit rota vol(Collarbone_d+Inc0)=-.25*PI,0;

//	a=.0125*PI;
	a=.005*PI;
	limit rota vol((Blade_g,Blade_d)+inc0)=-a,a;
	limit rotx vol((Blade_g,Blade_d)+inc0)=-a,a;
	limit speed rota vol(Body+inc0)=12;
}

body_limit_rota(f, a1,a2, ax1,ax2)
{

	limit rota vol(f)=a1,a2;
	if(ax1!=NIL && ax2!=NIL)limit axis vol(f)=ax1,ax2;
}

body_attach(inc0)
{
#include "body_externs()"

	inc1=inc0*Inc0;
	body_attach_blade(0,inc0);

	body_attach_blade(1,inc0);
	body_attach_collarbone(0,inc0);
	body_attach_collarbone(1,inc0);

	body_attach_buttock(1,inc0);
	body_attach_buttock(-1,inc0);

	body_attach_femur(0,1,inc0);body_attach_femur(1,-1,inc0);
	body_attach_tibia(0,1,inc0);
	body_attach_tibia(1,-1,inc0);

	body_attach_humerus(0,1,inc0);
	body_attach_humerus(1,-1,inc0);
	body_attach_radius(0,1,inc0);
	body_attach_radius(1,-1,inc0);

	belly=Belly+inc1;
	thorax1=Thorax1+inc1;thorax2=Thorax2+inc1;

	thorax3=Thorax3+inc1;thorax4=Thorax4+inc1;
	neck=Neck+inc1;head=Head+inc1;
/*
	a=limit rota vol(thorax3);a0=a[0];a1=a[1];
*/
}

body_attach_buttock(sens,inc0)
{
#include "body_externs()"

	if(sens>0)
		inc=inc0*Inc0;
	else
		inc=inc0*Inc0+Inc;
	femur=Femur_g+inc;buttock1=Buttock1_g+inc;
	buttock2=Buttock2_g+inc;
	a=limit rota vol(femur);a0=a[0];a1=a[1];
//	attach(0)rota(-.75*a0,a1)vol(buttock1)
	attach(0)rota(-.3*a0,a1)vol(buttock1)
		rota(a)vol(femur)ini;
	attach(0)rota(-.125*a0,.825*a1)vol(buttock2)
		rota(a)vol(femur)ini;
/*
	attach(0)dilx(1,1.05)vol(buttock1)
		rota(a)vol(femur)ini;
*/
	attach(0)rota(.25*PI,-.25*PI)vol(buttock1)
		rota(a)vol(femur)ini;
}
body_attach_femur(inc,sens,inc0,n1,k)
{
#include "body_externs()"

	inc=inc*Inc+inc0*Inc0;if(n1==NIL)n1=0;
	k=Body_Coe[2]*Body_Large[2];
	femur=Femur_g+inc;tibia=Tibia_g+inc;
	a=limit rota vol(tibia);
	w=vertex secy(2)vol(femur);
//	attach(n1)dila(k,k,k, 1.2*k,k,1.3*k)vertex(w)ini vol(femur)
	attach(n1)dila(k,k,k, 1.1*k,k,1.3*k)vertex(w)ini vol(femur)rota(a)vol(tibia);

	w=vertex secy(3,4)vol(femur);
	attach(0)dila(k,k,k, 1.3*k,k,1.4*k)vertex(w)ini vol(femur)rota(a)vol(tibia);

	a=limit rota vol(femur);
	w=vertex secy(3,4)vol(femur);
	attach(0)dilx(1,1.05)vertex(w)ini vol(femur)rota(a)vol(femur);
	w=vertex secy(5)vol(femur);
	attach(0)dilx(1,.85)vertex(w)vol(femur)rota(a)vol(femur)ini;
}
body_attach_tibia(inc,sens,inc0,n1)
{
#include "body_externs()"

	inc=inc*Inc+inc0*Inc0;if(n1==NIL)n1=0;
	k=Body_Coe[2]*Body_Large[2];
	tibia=Tibia_g+inc;a=limit rota vol(tibia);
	w=vertex secy(3)vol(tibia);
	attach(n1)dila(k,k,k, 1.3*k,k,1.4*k)vertex(w)ini vol(tibia)rota(a)vol(tibia);
}
body_attach_humerus(inc,sens,inc0)
{
#include "body_externs()"

	inc0*=Inc0;inc=inc*Inc+inc0;
	if(n1==NIL)n1=0;k=Body_Coe[2]*Body_Large[2];
	humerus=Humerus_g+inc;rad=Radius_g+inc;thorax4=Thorax4+inc0;

	a=limit rota vol(rad);
	w=vertex secy(3)vol(humerus);
	attach(1)dila(1.75*k,1,1.65*k, 1.1*k,1,1.05*k)vertex(w)ini vol(humerus)rota(a)vol(rad);
	if(inc)fem=Femur_d+inc0;else fem=Femur_g+inc0;
}

body_attach_radius(inc,sens,inc0,n1)
{
#include "body_externs()"

	inc0*=Inc0;inc=inc*Inc+inc0;if(n1==NIL)n1=0;
	k=Body_Coe[2]*Body_Large[2];
	rad=Radius_g+inc;hum=Humerus_g+inc;
	if((validate vol(rad)==NIL) || (validate vol(hum)==NIL))return;
	a=limit rota vol(rad);
	w=vertex secy(3)vol(rad);
//attach(n1)dila(1.6*k,k,1.8*k, k,k,k)vertex(w)ini vol(rad)rota(a)vol(rad);

	attach(n1)dila(1.4*k,k,1.4*k, k,k,k)vertex(w)ini vol(rad)rota(a)vol(rad);
}

body_attach_blade(inc,inc0)
{
extern Humerus_g,Blade_g,Inc,Inc0;

	inc=inc*Inc+inc0*Inc0;
	humerus=Humerus_g+inc;f=Blade_g+inc;
/*
	a=limit rota vol(humerus);if(a==NIL)return;
	attach(0)rota(.075*a)vol(f)rota(a)vol(humerus);
*/
	attach(0)axis vol(f)axis vol(humerus);
}

body_attach_collarbone(inc,inc0)
{
extern Humerus_g,Collarbone_g,Inc,Inc0;

	inc=inc*Inc+inc0*Inc0;
	humerus=Humerus_g+inc;f=Collarbone_g+inc;
	a=limit rota vol(humerus);if(a==NIL)return;
	attach(0)rota(.25*a)vol(f)rota(a)vol(humerus);
}

body_attach_spine(inc0)
{
return;
#include "body_externs()"

	inc0*=Inc0;f=Skin_Spine+inc0;s_g=Skin_Arm_g+inc0;s_d=Skin_Arm_d+inc0;
/* Spine -> Arms */
	w7=vertex secy(7)vol(f);nx=secx vol(f);ny=secy vol(s_g);
	w6=vertex secx(6)vol(s_g);attach(0)normal vertex(w7[0,2])vol(f)vertex(w6[ny,ny-2])vol(s_g);
	w2=vertex secx(2)vol(s_d);attach(0)normal vertex(w7[nx-2,nx-1])vol(f)vertex(w2[ny,ny-1])vol(s_d);
}

body_gen_1(x,y,z,f,an,nx,ny)
{
	p=NIL;for(i=0,ny)p,=1,.5-i/ny,0;
	rev(f)secx(nx)poi(p);
	illum vol(f)=1,1,.1,.1,0,0;
	col vol(f)=1,1,1;
	rotz(an)vol(f);
	dila(x,y,z)vol(f);
}
/*!!! open grid
body_gen_2(x,y,z,f,an,nx,ny,sens)
{
	grid(f)secx(nx+2)secy(ny);
	if(ny)
	{
		for(i=0,ny)p,=1,.5-i/ny,0;
	}
	else
		p=1,0,0;
	dan=2*PI/nx;
	if(sens>0)
		roty(-dan)var("p");
	else
		roty(PI-dan)var("p");
	for(i=1,nx+3)
	{
		w=vertex secx(i)vol(f);poi(w)vol(f)=p;
		roty(dan)var("p");
	}
	illum vol(f)=1,1,.1,.1,0,0;
	col vol(f)=1,1,1;
	rotz(an)vol(f);
	dila(x,y,z)vol(f);
}
!!!*/
/* ANCHORAGES */
/* ========== */

body_anc(inc0)
{
#include "body_externs()"

	if(inc0==NIL)inc0=0;inc2=inc0*Inc0;
	if(validate vol(Pelvis+inc2)==NIL)return;
	body_anc_Spine(inc0);
	body_anc_Leg(0,1,inc0);body_anc_Leg(1,-1,inc0);
	body_anc_Arm(0,1,inc0);body_anc_Arm(1,-1,inc0);
	body_anc_Sex(inc0);
	validate(1)poi vol(Body+inc2);
}

body_anc_Spine(inc0)
{
#include "body_externs()"

	inc0*=Inc0;
	pelvis=Pelvis+inc0;belly=Belly+inc0;
	thorax1=Thorax1+inc0;thorax2=Thorax2+inc0;
	thorax3=Thorax3+inc0;thorax4=Thorax4+inc0;
	neck=Neck+inc0;head=Head+inc0;hair=Hair+inc0;
	face=Face+inc0;robe=Robe+inc0;
	x=.2*X_Spine;y=.6*Y_Spine/(Nb_Spine-1);
	dy=1.6*y;dy2=1.3*dy;
/* Pelvis -> Belly */
	ny=secy vol(pelvis);
	w=vertex secy(ny+1)vol(pelvis);s=w[Nx1];
	g=poi(Nx1+1)vol(belly);
//	lead(pelvis)vertex(s)follow(belly)poi(g+(-x,.75*dy2,0));
	lead(pelvis)vertex(s)follow(belly)poi(g+(-x,.8*dy2,0));
/* Belly -> Thorax1 */
	g=poi(Nx1+1)vol(thorax1);
	lead(belly)vertex(Nx1+1)follow(thorax1)
		poi(g+(x,1.5*dy2,0));
/* thorax1 -> thorax2 */
	f=thorax1;
	g=poi(Nx1+1)vol(f+1);
	lead(f)vertex(Nx1+1)follow(f+1)poi(g+(1.5*x,.75*dy2,0));
/* thorax2 -> thorax3 */
	f++;g=poi(Nx1+1)vol(f+1);
	lead(f)vertex(Nx1+1)follow(f+1)poi(g+(.5*x,dy,0));
/* thorax3 -> thorax4 */
	f++;g=poi(Nx1+1)vol(f+1);
	lead(f)vertex(Nx1+1)follow(f+1)poi(g+(0,dy,0));
/* thora4 -> Neck */
//dy*=1.25;
dy*=1.4;
	p=(poi(Nx1+1)vol(neck))+(0,.8*dy,0);
	lead(thorax4)vertex(Nx1+1)follow(neck)poi(p);
/* thora4 -> Robe */
/*
	g=CG vol(thorax4);
	lead(thorax4)poi(g)follow(robe)poi(g);
*/
/* Neck -> Head */
	w1=vertex secy(1)vol(head);
//	p=(poi(w1[Nx1])vol(neck))+(.1*X_Spine,-1.5*dy,0);
	p=(poi(w1[Nx1])vol(neck))+(.1*X_Spine,-.8*dy,0);
	lead(neck)poi(p)follow(head)vertex(w1[Nx1]);
/* Head -> Face */
	lead(head)poi(0,0,0)follow(face)poi(0,0,0);
/* Head -> Hair */
	lead(head)poi(0,.75*R_Head,0)follow(hair)poi(0,0,0);
}

body_anc_Sex(inc0)
{
#include "body_externs()"

	d=R_Sex*Sex[inc0];inc0*=Inc0;
	f0=Sex0+inc0;f1=Sex1+inc0;f2=Sex2+inc0;pelvis=Pelvis+inc0;
	g1=CG secy(2)vol(pelvis);g2=CG secy(1)vol(f0);d=.5*R_Sex,0,0;
	lead(pelvis)poi(g1+(.33*X_Pelvis,0,0))follow(f0)poi(g2);
	g1=CG secy(2)vol(f0);g2=CG secy(1)vol(f1);
	lead(f0)poi(g1+d)follow(f1)poi(g2-d);
	g1=CG secy(2)vol(f1);g2=CG secy(1)vol(f2);
	lead(f1)poi(g1)follow(f2)poi(g2+(0,.1*R_Sex,0));

}

body_anc_Leg(inc,sens,inc0)
{
#include "body_externs()"

	inc0*=Inc0;
	inc=inc*Inc+inc0;pelvis=Pelvis+inc0;
	buttock1=Buttock1_g+inc;buttock2=Buttock2_g+inc;
	femur=Femur_g+inc;knee=Knee_g+inc;tibia=Tibia_g+inc;
	foot=Foot_g+inc;toe=Toe_g+inc;
	dx=.275*R_Leg;dy=.3*R_Leg;
/* pelvis -> femur */
	w=vertex secy(3)vol(pelvis);
	s=w[0];g1=poi(s)vol(pelvis);
	g1+=-dx,.225*Y_Pelvis,.45*sens*Z_Pelvis;
	w=vertex secy(5)vol(femur);
	s=w[0];g2=poi(s)vol(femur);
	g2+=-dx,-.8*Y_Pelvis,0;
	lead(pelvis)poi(g1)follow(femur)poi(g2);
/* femur -> buttock1 */
	nyh=secy vol(femur);wh=vertex secy(nyh+1)vol(femur);
	g=poi(wh[0])vol(femur);y=-R_Leg;
	lead(femur)poi(g+(0,y,0))follow(buttock1)vertex(1);
/* pelvis -> buttock2 */
	dilx(.8)vertex([.75*Nx1,Nx1],[1,.25*Nx1])vol(femur);
	dx2=-.2*X_Pelvis;
	g2=poi(1) vol(buttock2);r=radius vol(buttock2);
//	dz3=sens*.033*Z_Pelvis;
dz3=sens*.066*Z_Pelvis;
	lead(pelvis)poi(g1+(0,-.05*Y_Femur,0))follow(buttock2)
		poi(g2+(dx2,0,2*dz3));
/* femur -> tibia */
	lead(femur)poi(0,.55*Y_Femur,0)follow(tibia)
		poi(.1*R_Leg,-.6*Y_Tibia,0);
/* tibia -> knee */
	lead(tibia)poi(0,-.6*Y_Tibia,0)follow(knee)poi(0,0,0);
/* tibia -> foot */
	ny=secy vol(foot);g=CG secy(ny+1)vol(foot);
	lead(tibia)poi(0,.6*Y_Tibia,0)follow(foot)poi(g);
/* foot -> toe */
	g1=CG secy(1)vol(foot);ny=secy vol(toe);
	g2=CG secy(ny+1)vol(toe);d=.1*X_Foot;
	lead(foot)poi(g1+(d,0,0))follow(toe)
		poi(g2+(-d,-.25*Y_Foot,0));
}

body_anc_Arm(inc,sens,inc00)
{
#include "body_externs()"

	inc0=inc00*Inc0;inc2=inc*Inc+inc0;
	humerus=Humerus_g+inc2;coll=Collarbone_g+inc2;
	blade=Blade_g+inc2;wing=Wing_g+inc2;
	r=Radius_g+inc2;hand=Hand_g+inc2;thorax3=Thorax3+inc0;
	thorax4=Thorax4+inc0;
/* thorax4 -> collarbone */
	lead(thorax4)vertex(1)follow(coll)vertex(1);
/* collarbone -> blade */
	ny=secy vol(coll);g=CG secy(ny+1)vol(coll);
	gs=(CG vol(blade))+(0,-R_Arm,0);
	lead(coll)poi(g+(-1.15*R_Arm,0,-.65*sens*Z_Spine))
		follow(blade)poi(gs);
/* blad -> wing */
/*
	g=CG vol(blade);n=secy vol(wing);
	w=vertex secy(n+1)vol(wing);
	lead(blade)poi(g)follow(wing)vertex(w[0]);
*/
/* collarbone -> humerus */
	ny=secy vol(humerus);gh=CG secy(ny+1)vol(humerus);
	ph=gh+(R_Arm,-.5*R_Arm,.33*sens*R_Arm);
	ny=secy vol(humerus)coll;
	ps=(CG secy(ny+1)vol(coll))+(0,0,sens*R_Arm);
//	ps=g+(-.5*R_Arm,0,sens*.75*R_Arm);
	lead(coll)poi(ps)follow(humerus)poi(ph);
/* humerus -> radius */
	g1=CG secy(1)vol(humerus);
	x=-.5*R_Arm;y=.15*Y_Radius;
	n=secy vol(r);g2=CG secy(n+1)vol(r);
	lead(humerus)poi(g1+(x,y,0))follow(r)
		poi(g2+(x,-y,0));
/* radius -> hand */
	lead(r)poi(0,.55*Y_Radius,0)follow(hand)
		poi(0,-.55*Y_Hand,0);
/* radius -> wing */
//	lead(r)vertex(1)follow(wing)vertex(1);
/* hand -> fingers */
	f1=Finger_g+inc2;
//	p=-2.75*R_Finger,.4*Y_Hand,0;dp=1.75*R_Finger,0,0;
	p=-2.5*R_Finger,.4*Y_Hand,0;dp=1.7*R_Finger,0,0;
	y=.5*Y_Finger;
/* Fingers */
	for(i=0,3)
	{
		y=.5*dist_secy(f1);
		lead(hand)poi(p)follow(f1)poi(0,-y);
		dy=.1*Y_Finger;
		for(j=1,2)
		{
			lead(f1)poi(0,y+dy)follow(f1+1)poi(0,-y-dy);
			f1++;dy*=K_Finger;
		}
		f1++;p+=dp;
	}
/* Thumb */
	p=CG secy(2)vol(hand);
	lead(hand)poi(p+(1.5*R_Finger,.33*Y_Hand,0))follow(f1)
		poi(0,-y);f0=f1;
dy=.025*Y_Finger;
	for(j=1,2)
	{
		lead(f1)poi(0,y+dy)follow(f1+1)poi(0,-y-dy);f1++;dy*=K_Finger;
	}
	rotz(-.25*PI)vol[f0,f0+2];
}
	
dist_secy(f)
{
	ny=secy vol(f);g1=CG secy(1)vol(f);g2=CG secy(ny+1)vol(f);return(dist(g1,g2));
}

set_rot(inc0)
{
#include "body_externs()"

	if(inc0==NIL)inc0=0;inc0*=Inc0;an=.01*PI;
	rotx (-an)vol(Femur_g+inc0);
	rotx (an)vol(Femur_d+inc0);
}

body_set_name(nn,f,sens,inc0)
{
extern Inc0;

	switch(sens)
	{
	case 1: nn,="_g_";break;
	case -1: nn,="_d_";break;
	default: nn,="_";
	}
	name vol(f)=nn,string(inc0/Inc0);
}

/* UTILITIES */
/* ========= */

/*********************************
s=0,s0,0, i,si,0, ..., 1,1,0)
a=0,k0,0, ai,ki,0, ...,100,k100,0)
returns coe
**********************************/
/* func body_size */
/* -------------- */
body_size(s,a,inc0)
{
extern Sex,Age,Beast;

	s=adjust(101)line(s)ext(20,1,1);
	sex=Sex[inc0];b=Beast[inc0];
//if(sex<0)sex=0;if(sex>1)sex=1;
	sex=s{100*sex};sex=sex[1];
	a=adjust(101)line(a)ext(20,1,1);
	age=Age[inc0];if(age<0)age=0;if(age>100)age=100;
	age=a{age};k=b*age[1];
	return(sex*k);
}

/* func body_adjustment */
/* -------------------- */
body_adjustment(inc0)
{
#include "body_externs()"

	if(inc0==NIL)inc0=0;inc2=inc0*Inc0;
	ks=K_Strength[inc0];
	breast=Body_Breast[inc0]=
		body_size((0,3,0, 1,.7,0),
		(0,0,0, 12,0,0, 18,1,0, 30,1,0, 100,0,0),inc0);
/* init */
/* ---- */
/* for absolute transformations */
	validate(-1)poi vol(Body+inc2);
	sex=Sex[inc0];pelvis=Pelvis+inc2;
	body=Body+inc2;belly=Belly+inc2;
	b1=Buttock1_g+inc2;b2=Buttock2_g+inc2;
	f1=Thorax1+inc2;f2=Thorax2+inc2;f4=Thorax4+inc2;
	femur=Femur_g+inc2;tibia=Tibia_g+inc2;
	humerus=Humerus_g+inc2;
	rad=Radius_g+inc2;hand=Hand_g+inc2;
/* Size */
/* ---- */
	t=body_size((0,1,0, 1,1.1,0),(0,.9,0, 12,.9,0, 18,1,0, 
		70,1,0, 100,.95,0),inc0);
/* Pelvis */
/* ------ */
	c=body_size((0,1.15,0, 1,1.1,0),(0,1.1,0, 18,1,0,
		100,.8,0),inc0);
////	dila(c,1,c)vol(b1,b2,b1+Inc,b2+Inc);
	c=1+.1*body_size((0,1,0, 1,1.1,0),(0,1.5,0, 12,.9,0, 18,1,0,
		30,1,0, 100,1.1,0),inc0);
	dila(c,1,c)vol(belly);
	cs=body_size((0,0,0, 1,1,0),(0,1,0, 12,.75,0, 18,1,0,
		100,1,0),inc0);
	hom(cs)vol((Sex0,Sex1,Sex2)+inc2);
	body_meta(inc0);body_Erec(inc0);
	t=body_size((0,1,0, 1,1.2,0),(0,.2,0, 12,.9,0, 18,1,0,
		70,1,0, 100,.95,0),inc0);
	dila(t,t,t)matrix vol(pelvis);
/* Head */
/* ---- */
	ch=body_size((0,1,0, 1,1,0),(0,2,0, 10,1.5,0, 12,1.2,0,
		18,1,0, 100,1,0),inc0);
	hom(ch)vol(Head+inc2);
/* Leg */
/* --- */
	c2=ks*body_size((0,1,0, 1,1,0),(0,1,0, 18,.9,0, 70,1,0,
		 100,.85,0),inc0);
	dila(c2,1,c2)vol(femur,femur+Inc,tibia,tibia+Inc);

	a=.02*PI*(1-sex);
	rotx(-a)vol(femur);rotx(a)vol(femur+Inc);
	k=body_size((0,0,0, 1,1,0),(0,.9,0, 12,.9,0, 18,1,0,
		70,.95,0, 100,.9,0),inc0);
	s=vertex lead vol(femur);p=poi(s)vol(pelvis);
	poi(s)vol(pelvis)=p-100*k/R_Leg;
	s=vertex lead vol(femur+Inc);p=poi(s)vol(pelvis);
	poi(s)vol(pelvis)=p+(0,0,100*k/R_Leg);
/* Arm */
/* --- */
	c=ks*body_size((0,1,0, .8,.9,0),(0,.8,0, 12,.9,0,
		18,1,0, 65,1,0, 100,.9,0),inc0);
	dila(c,1,c)vol(humerus,humerus+Inc,rad,rad+Inc);
	rotx(-a)vol(humerus);rotx(a)vol(humerus+Inc);
/* adjust attach */
/* ------------- */
	body_adjust_attach(inc0,t*ks);
}
body_adjust_attach(inc0,t)
{
#include "body_externs()"

	w=(Tibia_g,Femur_g,Radius_g,Femur_g)+Inc0;
	rem attach vol(w,w+Inc);
	body_attach_femur(0,1,inc0,1,2,t);
	body_attach_femur(1,-1,inc0,1,2,t);
	body_attach_tibia(0,1,inc0,1,2,t);
	body_attach_tibia(1,-1,inc0,1,2,t);
	body_attach_humerus(0,1,inc0);
	body_attach_humerus(1,-1,inc0);
	body_attach_radius(0,1,inc0,1,2,t);
	body_attach_radius(1,-1,inc0,1,2,t);
}
/* For application */
body_adjust(inc0)
{
return;
#include "body_externs()"

}

/* =============
FOR APPLICATIONS
================ */

BODY_SCALES()
{
extern CLI,MES,EXEC,Limit;

	set_message(CLI,"click on num");MES=EXEC=NIL;
	interaction("ini");eye(750);
}
func_BODY_SCALES()
{
#include "body_externs()"

	y1=Y1_SCA+Dy2;x2=.33*X2_SCA;Num_Body[1]=Nb_Body[2];ret=NIL;
	nb=scale("nb")poi(X1_SCA,y1)coe(Nb_Body)
		rectangle(KR)frame ent(1);y1+=Dy2;
	if(nb==NIL)return;	/* : */
	nb0=Nb_Body[2];Nb_Body[2]=nb;w=Body,Skin;
	if(nb==0)
	{
		for(i=1,nb0)
		{
			rem vol(w,-w);w+=Inc0;
		}
		return;
	}
	if(nb!=nb0)
	{
		for(i=1,nb0)
		{
			rem vol(w,-w);w+=Inc0;
		}
		for(i=1,nb)
		{
			body(i-1);body_set_num(i);
		}
		ret=1;
	}
	return(ret);
}
BODY_PARAM()()
{
extern CLI,MES,EXEC,Limit;

	set_message(CLI,"change the scales");MES=EXEC=NIL;
	interaction("ini");eye(750);
}
func_BODY_PARAM()
{
#include "body_externs()"

	if((nb=Nb_Body[2])==0)return;
	y1=Y1_SCA+2*Dy2;Num_Body[1]=nb;x2=.33*X2_SCA;
	num=scale("num")poi(X1_SCA,y1)coe(Num_Body)rectangle(KR)
		frame ent(1);
	if(num==NIL)return;	/* : */
	Num_Body[2]=num;cpt=0;
	if(num==0)return;num--;
	age=0,100,Age[num],18;sex=0,1,Sex[num],0;
	beast=0,2,Beast[num],1;erec=0,1,Erec[num],0;
	k_strength=.5,1.5,K_Strength[0],1;
	y1+=Dy2;age[1]=30;

	w=scale("age;sex;beast")poi(X1_SCA,y1,x2-10,y1+Dy1)
		coe(age,sex,beast)format(1,3)frame displ;
	w0=w[0];w1=w[1];w2=w[2];
	if((w0!=Age[num]) || (w1!=Sex[num]) || (w2!=Beast[num]))
	{
		Age[num]=w0;Sex[num]=w1;Beast[num]=w2;
		body_adjustment(num);cpt++;
	}
	if(w1)
	{
		w=scale("erec")poi(x2+10,y1,X2_SCA,y1+Dy1)coe(erec)
			frame displ;
		if(w!=Erec[num])
		{
			Erec[num]=w;body_Erec(num);cpt++;
		}
	}
	y1+=Dy2;strength=.5,1.5,K_Strength[num],1;
	breast=.5,2,Body_Breast[num],1;
	w=scale("strength;breast")poi(X1_SCA,y1,X2_SCA,y1+Dy1)
		format(1,2)coe(strength,breast)frame displ;y1+=Dy2;
	s=w[0];b=w[1];
	if((s!=K_Strength[num]) || (b!=Body_Breast[num]))
	{
		K_Strength[num]=s;Body_Breast[num]=b;
		body_adjustment(num);cpt++;
	}
	cs=Col_Skin{num};r=cs[0];g=cs[1];b=cs[2];

/*??? BUG
	w=scale("col skin")poi(X1_SCA,y1,X2_SCA,y1+Dy1)
		coe(0,1,r,1, 0,g,1,0, 0,b,0,1)format(1,3)frame displ;y1+=Dy2;
???*/
	w0=w[0];w1=w[1];
//w2=w[2];

	dx=(X2_SCA-X1_SCA)/4;x1=X1_SCA+dx;x2=x1+dx;x3=x2+dx;
	w0=scale("r skin")poi(X1_SCA,y1,x1,y1+Dy1)
		coe(0,1,r,1)frame displ;
	w1=scale(" g skin")poi(x1,y1,x2,y1+Dy1)
		coe(0,1,g,1)frame displ;
	w2=scale(" b skin")poi(x2,y1,X2_SCA,y1+Dy1)
		coe(0,1,b,1)frame displ;y1+=Dy2;
	if(w0!=r || w1!=g || w2!=b)
	{
		Col_Skin{num}=c=w0,w1,w2;col vol(Skin+num*Inc0)=c;
	}

	cs=Col_Hair{num};r=cs[0];g=cs[1];b=cs[2];
	w=scale("d hair")poi(X1_SCA,y1,x1,y1+Dy1)
		coe(0,2,K_Hair0,1)frame displ;
	w0=scale("r hair")poi(x1,y1,x1,y1+Dy1)
		coe(0,1,r,1)frame displ;
	w1=scale(" g hair")poi(x2,y1,x2,y1+Dy1)
		coe(0,1,g,1)frame displ;
	w2=scale(" b hair")poi(x3,y1,X2_SCA,y1+Dy1)
		coe(0,1,b,1)frame displ;y1+=Dy2;
	if(w!=K_Hair0)
	{
		K_Hair[num]=K_Hair0=w;
	}
	if(w0!=r || w1!=g || w2!=b)
	{
		Col_Hair{num}=c=w0,w1,w2;
		col vol(Hair+num*Inc0)=c;validate vol(Hair)=1;
	}
	if(cpt)
	{
		body(0);body_adjustment(0);
	}
}
/* body_set_num */
/* ------------ */
body_set_num(num)
{
#include "body_externs()"

	if(num==0)return;
	num--;inc=num*Inc0;pelvis=Pelvis+inc;
	if (validate vol(pelvis)==NIL)body(num);
	body=Body+inc;
	validate vol(pelvis)=-5;validate vol(Skin+inc)=1;
	no dynamic;
	tran(0,0,0)matrix vol(pelvis);
	rota(0)matrix vol(body);rotx(0)matrix vol(body);
	roty(0)matrix vol(body);

	Bod_Roty[num]=an=num*PI/Nb_Body[2];
	roty(an)matrix vol(pelvis);

	x=D*cos(an);z=D*sin(an);tran(x,0,z)matrix vol(pelvis);
	rotz(0)matrix vol(body);
	rem traj vol(body);
	Num_Param=num;
}

body_get_anc(f,sens)
{
	g=limit vol(f);
	if(sens>0)
		g=g[3],0,g[5];
	else
		g=g[3],0,g[2];
	return(g);
}
body5()
{
return;
#include "body_externs()"

	nb=Nb_Body[2];
	col_g=Collarbone_g;col_d=Collarbone_d;np=NP vol(Collarbone_g);
	th4=Thorax4;th3=Thorax3;
	for(i=0,nb-1)
	{
		an=rota matrix vol(col_g);rotx(an)ini vertex[2,6]vol(th4);
		an=rota matrix vol(col_d);rotx(an)ini vertex[8,12]vol(th4);
		col_g+=Inc0;col_d+=Inc0;th4+=Inc0;
	}
}
body_hand_to_hand()
{
#include "body_externs()"

	if((nb=Nb_Body[2])<2)return;
	n1=0;n2=Inc0;p1=Pelvis;h=Hand_g;
	p20=Hand_d,Radius_d,Humerus_d;
	for(i=1,nb)
	{
		p2=p20;g=CG matrix vol(h);
		for(j=1,nb)
		{
			if(j!=i)
			{
				tran inv vol(p2)poi(g)
					force(Body_Hand_To_Hand[2]);
			}
			p2+=Inc0;
		}
		p1+=Inc0;h+=Inc0;
	}
}
body_ini_param(nb)
{
#include "body_externs()"

	Nb_Body=0,C,0,0;
	Num_Body=0,Max_Nb_Body,0,0;
	Age=calloc(Max_Nb_Body,18);
	Sex=Erec=calloc(Max_Nb_Body,0);
	K_Hair=calloc(Max_Nb_Body,K_Hair0);
	K_Strength=calloc(Max_Nb_Body,1);
	Body_Breast0=.2;
	Body_Breast=calloc(Max_Nb_Body,Body_Breast0);
	Col_Hair=calloc(3*nb);
}
body_set_limit_rota()
{
#include "body_externs()"

	nb=Nb_Body[2];
	col_g=Collarbone_g;col_d=Collarbone_d;
	hum_g=Humerus_g;hum_d=Humerus_d;
	for(i=1,nb)
	{
		limit rota vol(col_g)=PI*(0,.25);
		limit rota vol(col_d)=PI*(-.25,0);
		limit rota vol(hum_g)=PI*(.15,.75);
		limit rota vol(hum_d)=PI*(-.75,-.15);
		col_g+=Inc0;col_d+=Inc0;hum_g+=Inc0;hum_d+=Inc0;
	}
}
/* ======= */
/* GENETIC */
/* ======= */
body_genetic(inc0)
{
#include "body_externs()"

	nb=6;
	g=Body_Genetic+inc0;
	prob=Body_Prob[2];muta=Body_Muta[2];t=Body_Size[2];
	genetic(g);
	meta alea genetic(g)=prob,muta;
	generate rand particle(nb,t)genetic(g);
	func genetic(g)="Body_Fitness";
}
Body_Fitness(g,num,p)
{
	v=(ascii(p))-'0';
	return(average(v));
}
body_set_smile(inc,ni,c)
{
#include "body_externs()"
return;	/*??? BUG ???*/
	face=Face+inc*Inc0;
	if((n=secx vol(face))==NIL)return;
	n/=2;
	wm=vertex secy(3)vol(face);	/* mouth */
	we=vertex secy(7)vol(face);	/* eye */
	s=wm[n-1];dy=c*R_Head;
	wg=wm[n-1],we[n-1];
	wd=wm[n+1],we[n+1];
	wg=wm[n-1],wm[n+1];
	n=dim(wg);dp=0,dy,0;
	for(i=0,n-1)
	{
		s=wg[i];p=poi(s)vol(face);
		z1=p[2];dp[2]=z1-2*z1*i/(n-1);
		traj(ni)tran(p,p+dp,p)
			vertex(s)vol(face)abs pend;
		s=wd[i];p=poi(s)vol(face);
		z1=p[2];dp[2]=z1+2*z1*i/(n-1);
		traj(ni)tran(p,p+dp,p)
			vertex(s)vol(face)abs pend;
	}
}
/* func body_set_col */
/* ----------------- */
body_set_col(c)
{
#include "body_externs()"

	if(c==NIL)c=3;
	nb=Nb_Body[1];Col_Skin=Col_Hair=calloc(3*nb);k=0;
	switch(Body_Col)
	{
	case 1:	/* non reproductible random */
		for(i=0,nb-1)
		{
			Col_Skin{i}=rand2f(c*(.5,1)),
				rand2f(c*(.2,.5)),rand2f(c*(0,.25));
			Col_Hair{i}=rand2f(c*(0,.2)),
				rand2f(c*(0,.4)),rand2f(c*(0,.6));
		}
		break;
	case 2:	/* reproductible random */
		for(i=0,nb-1)
		{
			Col_Skin{i}=c*(alea(k),alea(k+1),alea(k+2));
			Col_Hair{i}=c*(alea(k+3),alea(k+4),alea(k+5));
			k+=6;
		}
		break;
	case 3:	/* datas */
Col_Skin{0}=.75,.5,.25;Col_Hair{0}=0,0,0;	/* orange */
		if(nb<2)return;
Col_Skin{1}=.75,.5,.25;Col_Hair{0}=0,0,0;	/* orange */
		if(nb<3)return;
//Col_Skin{2}=.75,.5,.25;Col_Hair{2}=0,0,0;/* yellow */
Col_Skin{2}=1,.4,.2;Col_Hair{0}=0,0,0;	/* orange */
		if(nb<4)return;
Col_Skin{3}=1,.8,.6;Col_Hair{3}=1,.5,0;	/* light */
		if(nb<5)return;
Col_Skin{4}=.25,1,.5;Col_Hair{4}=.1,.25,.5;	/* green */
		if(nb<6)return;
Col_Skin{5}=1,.5,.6;Col_Hair{5}=1,0,0;		/* light */
		if(nb<7)return;
Col_Skin{6}=.5,.3,.5;Col_Hair{6}=1,0,1;	/* purple */
		if(nb<8)return;
Col_Skin{7}=.3,.3,.3;Col_Hair{7}=1,1,1;	/* grey */
		if(nb<9)return;	
Col_Skin{8}=0,0,0;Col_Hair{8}=0,0,0;		/* black */
		if(nb<10)return;
		for(i=10,nb-1)
		{
			Col_Skin{i}=alea(k),alea(k+1),alea(k+2);
			Col_Hair{i}=alea(k+3),alea(k+4),alea(k+5);k+=6;
		}
		break;
	}
	nb=Nb_Body[2];skin=Skin;
//hair=Hair;
hair=Hair;
face=Face;
	for(i=0,nb-1)
	{
		rem traj col vol(skin);
		col vol(skin,face)=c=Col_Skin{i};
		col vol(hair)=Col_Hair{i};
		col vol(face)=(1.5,1,1)*c;
		skin+=Inc0;hair+=Inc0;face+=Inc0;
	}
}
/* func body_option */
/* ---------------- */
body_option(option,inc0)
{
#include "body_externs()"

	$"body_option = ",option;NL;
	if((n1=dim(option))==0)return;k=0;n2_max=0;
	while(1)
	{
		w=body_get_option(option[k,n1-1]);
		if((ni=dim(w))==0)return;
		if(ni==3)	/* opt */
		{
			switch(w)
			{
			case("deb"): Debug=1;break;
			}
		}
		else
		{
/*
			if(ni==6)
			{
				switch(w)
				{
				case("haidat"):
					Body_Col=3;body_set_col();break;
				}
				goto suite;
			}
*/
			if(ni>3)
			{
				w3=w[3];
				if(w3=="=")
				{
					w0=w[0,2];
					switch(w0)
					{
					case("bod"):
						if(ni>4)
						{
							w4n=w[4,ni-1];
							if((w[3])=="=")
							{
								nb=atoi(w[4,ni-1]);
							Nb_Body[2]=Nb_Body1=nb;
						Sex=calloc(Max_Nb_Body);
								Num_Body=0,nb,0,0;
								body_set_col();
							}
						}
						break;
					case("dim"):
						if(ni>4)
						{
							D=atof(w[4,ni-1]);
							body_get_size();break;
						}
					case("lar"):
						if(ni>4)
						{
							if((w[3])=="=")
							{
								Body_Large[2]=atof(w[4,ni-1]);
							}
						}
						break;
					case("sex"):
						if(ni>4)
						{
							if((w[3])=="=")
							{
							sex=atof(w[4,ni-1]);
						Nb_Body[2]=Nb_Body1=dim(sex);
								if(n2=dim(sex))
								{
							if(n2>n2_max)n2_max=n2;
							for(j=0,n2-1)Sex[j]=sex[j];
								}
								else
								{
							if(inc0>=0)Sex[inc0]=sex;
								}
								Nb_Body[2]=n2;
//								body_set_col();
							}
						}
						break;
					case("age"):
						if(ni>4)
						{
							if((w[3])=="=")
							{
							age=atof(w[4,ni-1]);
	//						Nb_Body[2]=dim(age);
								if(n2=dim(age))
								{
//Nb_Body[2]=n2;
							if(n2>n2_max)n2_max=n2;
							for(j=0,n2-1)Age[j]=age[j];
								}
								else
								{
							if(inc0>=0)Age[inc0]=age;
								}
							}
						}
						break;
					case("bea"):
						if(ni>4)
						{
							if((w[3])=="=")
							{
								bea=atof(w[4,ni-1]);
								Nb_Body[2]=dim(bea);
								if(n2=dim(bea))
								{
									if(n2>n2_max)
										n2_max=n2;
									for(j=0,n2-1)
									Beast[j]=bea[j];
								}
								else
								{
							if(inc0>=0)Bea[inc0]=bea;
								}
								Nb_Body[2]=n2;
//								body_set_col();
							}
						}
						break;
					case("hai"):
						if(ni>4)
						{
							if((w[3])=="=")
							{
							K_Hair0=atof(w[4,ni-1]);
							Nb_Body[2]=nh=dim(K_Hair0);
							K_Hair=calloc(Max_Nb_Body);
							K_Hair[0,nh-1]=K_Hair0;
//					K_Hair=calloc(Max_Nb_Body,K_Hair0);
							}
						}
						break;
					case("str"):
						if(ni>4)
						{
							if((w[3])=="=")
							{
								s=atof(w[4,ni-1]);
								if(n2=dim(h))
								{
									if(n2>n2_max)n2_max=n2;
									for(j=0,n2-1)K_Strength[j]=s[j];
								}
								else
								{
									if(inc0>=0)K_Strength[inc0]=s;
								}
							}
						}
						break;
					case("bre"):
					if(ni>4)
						{
							if((w[3])=="=")
							{
						bb=atof(w[4,ni-1]);
$"w=",w;NL;$"bb=",bb;NL;
						Nb_Body[2]=nh=dim(bb);
			Body_Breast=calloc(Max_Nb_Body,Body_Breast0);
						Body_Breast[0,nh-1]=bb;
							}
						}
						break;
					}
				goto suite;
				}
			}
			n0=dim(w);
			if(n0>=8)
			{
				if((w[6])=="=")
				{
					w0=w[0,5];
					switch(w0)
					{
					case("colhai"):
						ch=atof(w[7,ni-1]);
						n2=dim(ch);np=n2/3;
						if(np)
						{
							if(np>n2_max)n2_max=np;
							for(j=0,np-1)Col_Hair{j}=ch{j};
						}
						else
						{
							if(inc0>=0)Col_Hair{inc0}=ch;
						}
						Body_Col=0;break;
					case("colski"):
						ch=atof(w[7,ni-1]);
						n2=dim(ch);np=n2/3;
						if(np)
						{
							if(np>n2_max)n2_max=np;
							for(j=0,np-1)Col_Skin{j}=ch{j};
						}
						else
						{
							if(inc0>=0)Col_Skin{inc0}=ch;
						}
						Body_Col=0;break;
					}
				}
			}
		}
suite:
		k+=ni+1;if(k>=n1)return;
	}
}
body_get_option(w)
{
	n=dim(w);w1=NIL;k=0;
	while(n-->0)
	{
		wk=w[k];
		if(wk==";")return(w1);
		w1,=wk;k++;
	}
	return(w1);
}
body_spring_hair(s,v)
{
extern Bod_Sti,Bod_Vis,Nb_Body,Hair,Inc0;

	if(s==NIL)s=Bod_Sti[2];
	if(v==NIL)v=Bod_Vis_Hair[2];
	nb=Nb_Body[2];h=Hair;
	for(i=1,nb)
	{
		spring vol(h)=s,v;h+=Inc0;
	}
}
body_spring_wing(s,v)
{
#include "body_externs()"

	if(s==NIL)s=Bod_Sti[2];
	if(v==NIL)v=Bod_Vis[2];
	nb=Nb_Body[2];h=Wing_g,Wing_d;
	for(i=1,nb)
	{
		spring vol(h)=s,v;h+=Inc0;
	}
}

/* body_set_roty */
/* ------------- */
body_set_roty()
{
#include "body_externs()"

	nb=Nb_Body[2];pel=Pelvis;
	for(i=0,nb-1)
		Bod_Roty[i]=i*PI/nb;
}
set_Wing()
{
#include "body_externs()"

	if(validate vol(Wing_g)==NIL)return;
	if((nb=Nb_Body[2])==0)return;
	fg=Wing_g;rg=Radius_g;hg=Humerus_g;pel=Pelvis;belly=Belly;
	fd=Wing_d;rd=Radius_d;hd=Humerus_d;d=D;d1=.5*D;
	ny=secy vol(Pelvis);n=NP abs vol(hg);
	f1=Skirt[0];f2=Skirt[1];
	fem_g=Femur_g;fem_d=Femur_d;
//	w=vertex secy(ny+1)vol(Pelvis);
s=.5*(NP vol(Femur_g));
	for(i=1,nb)
	{
		poi(1)vol(fg)=poi(1)anc vol(rg);
		poi(2)vol(fg)=poi(1)anc vol(hg);
		poi(3)vol(fg)=poi(n)anc vol(hg);
		poi(1)vol(fd)=poi(1)anc vol(rd);
		poi(2)vol(fd)=poi(1)anc vol(hd);
		poi(3)vol(fd)=poi(n)anc vol(hd);
		g=poi(s)anc vo(fem_g);
		adhere vol(fg,f1)ball(g,d);
		g=poi(s)anc vo(fem_d);
		adhere vol(fd,f2)ball(g,d);

		g0=poi(1)anc vol(pel);
		adhere vol(f1,f2)ball(g0,d1);

		poi[1,Nx1]vol(f1)=poi(Skirt1)anc vol(belly);
		poi[1,Nx1]vol(f2)=poi(Skirt2)anc vol(belly);
		adhere vol(fg,fd)ball(g0,d);
		fg+=Inc0;rg+=Inc0;pel+=Inc0;hg+=Inc0;belly+=Inc0;		fd+=Inc0;rd+=Inc0;hd+=Inc0;
		f1+=Inc0;f2+=Inc0;fem_g+=Inc0;fem_d+=Inc0;
	}
}
set_Hair()
{
#include "body_externs()"

	if(validate vol(Hair)==NIL)return;
	if((nb=Nb_Body[2])==0)return;
	hair=Hair;th3=Thorax3;
	d=D;
	for(i=1,nb)
	{
		g=CG matrix vo(th3);
			adhere vol(hair)ball(g,d);
		hair+=Inc0;th3+=Inc0;
	}
}

/*
set_Robe()
{
return;
#include "body_externs()"

	nb=Nb_Body[2];t4=Thorax4;f=Robe;
	if(validate vol(f)==NIL)return;
	rg=Radius_g;hg=Humerus_g;rd=Radius_d;hd=Humerus_d;
	d1=.5*D;d2=D;
	n=(NP vol(hg))-2;
	for(i=1,nb)
	{
		if(validate vol(t4)==NIL)return;
		poi(1)vol(f)=poi(1)anc vol(rg);
		poi(3)vol(f)=poi(1)anc vol(hg);
		poi(5)vol(f)=poi(n)anc vol(hg);
		poi(7)vol(f)=poi(Nx1)anc vol(t4);
		poi(9)vol(f)=poi(n)anc vol(hd);
		poi(11)vol(f)=poi(1)anc vol(hd);
		poi(13)vol(f)=poi(1)anc vol(rd);
		t4+=Inc0;f+=Inc0;rg+=Inc0;rd+=Inc0;hg+=Inc0;hd+=Inc0;
	}
}
*/
BUG()
{
#include "body_externs()"

	validate vol(Skin,Wing,Skirt+Inc0)=0;
	validate vol(Pelvis)=1;
}

/* END */