//
//	面を膨らませる
//

function PuffCenter(ver1, ver2)
{
	var pos1, pos2;
	var vec1, vec2;
	var pos, vec, ver;
	var pv;
	var cos1, cos2, sin1, sin2;
	var uv1[2], uv2[2];
	var theta;
	var nv;
	var l;

	pos1 = Position(ver1);
	pos2 = Position(ver2);

	vec1 = Vector(ver1);
	vec2 = Vector(ver2);
	vec = (vec1 + vec2);

	Mapping(ver1, uv1);
	Mapping(ver2, uv2);

	l = abs(vec1);
	if (l < 0.0001) return FALSE;
	vec1 = vec1 * (1.0/l);

	l = abs(vec2);
	if (l < 0.0001) return FALSE;
	vec2 = vec2 * (1.0/l);

	l = abs(vec);
	if (l < 0.0001) return FALSE;
	vec = vec * (1.0/l);

	pv = pos2 - pos1;
	nv = (pv * vec) * pv;
	l = abs(nv);
	if (l < 0.0001) return FALSE;
	nv = nv * (1.0/l);

	l = abs(pv);
	if (l < 0.0001) return FALSE;
	pv = pv * (1.0/l);

	cos1 =   pv . vec1;
	cos2 = - pv . vec2;

	sin1 = abs( pv * vec1 );
	sin2 = abs( pv * vec2 );

	theta = (atan2(sin1, cos1) + atan2(sin2, cos2) - PI) / 4.0;

	if ((PI/2-0.0001) < theta & theta < (PI/2+0.0001)) return FALSE;

	if (-0.01 < theta & theta < 0.01)
		return TRUE;

	pos = ((pos1 + pos2) * 0.5) + nv * (l * 0.5 * tan(theta));
	ver = Vertex(pos, vec * 256.0, (uv1[0]+uv2[0])/2, (uv1[1]+uv2[1])/2);
	return ver;
}

function Puff3()
{
	var vec1,vec2, vec3, vec12, vec23, vec31;
	vec1 = PolyGetVertex(0);
	vec2 = PolyGetVertex(1);
	vec3 = PolyGetVertex(2);

	vec12 = PuffCenter(vec1, vec2);
	vec23 = PuffCenter(vec2, vec3);
	vec31 = PuffCenter(vec3, vec1);

//	if (typeof(vec12) == BOOLEAN | typeof(vec23) == BOOLEAN | typeof(vec31) == BOOLEAN)
//		return;


	if (typeof(vec12) == BOOLEAN) {
		if (typeof(vec23) == BOOLEAN) {
			if (typeof(vec31) == BOOLEAN) {
				return;
			} else {
// 1 - 2 - 31, 31 - 2 - 3
//				PolySetVertex(vec1,  0);
//				PolySetVertex(vec2,  1);
				PolySetVertex(vec31, 2);
				PolyAppend(TRUE);

				PolySetVertex(vec31, 0);
//				PolySetVertex(vec2,  1);
				PolySetVertex(vec3,  2);
				PolySave();
			}
		} else {
			if (typeof(vec31) == BOOLEAN) {
// 1 - 2 - 23, 1 - 23 - 3
//				PolySetVertex(vec1,  0);
//				PolySetVertex(vec2,  1);
				PolySetVertex(vec23, 2);
				PolyAppend(TRUE);

//				PolySetVertex(vec1,  0);
				PolySetVertex(vec23, 1);
				PolySetVertex(vec3,  2);
				PolySave();

			} else {
// 1 - 2 - 23 - 31, 31 - 23 - 3
				PolySetVertex(vec31, 0);
				PolySetVertex(vec23, 1);
//				PolySetVertex(vec3,  2);
				PolyAppend(TRUE);

				PolyVertexs(4);
				PolySetVertex(vec1,  0);
				PolySetVertex(vec2,  1);
				PolySetVertex(vec23, 2);
				PolySetVertex(vec31, 3);
				PolySave();
			}
		}
	} else {
		if (typeof(vec23) == BOOLEAN) {
			if (typeof(vec31) == BOOLEAN) {
// 1 - 12 - 3, 12 - 2 - 3
//				PolySetVertex(vec1,  0);
				PolySetVertex(vec12, 1);
//				PolySetVertex(vec3,  2);
				PolyAppend(TRUE);

				PolySetVertex(vec12, 0);
				PolySetVertex(vec2,  1);
//				PolySetVertex(vec3,  2);
				PolySave();
			} else {
// 1 - 12 - 31, 12 - 2 - 3 - 31
//				PolySetVertex(vec1,  0);
				PolySetVertex(vec12, 1);
				PolySetVertex(vec31, 2);
				PolyAppend(TRUE);

				PolyVertexs(4);
				PolySetVertex(vec12, 0);
				PolySetVertex(vec2,  1);
				PolySetVertex(vec3,  2);
				PolySetVertex(vec31, 3);
				PolySave();
			}
		} else {
			if (typeof(vec31) == BOOLEAN) {
// 1 - 12 - 23 - 3, 12 - 2 - 23
				PolySetVertex(vec12, 0);
//				PolySetVertex(vec2,  1);
				PolySetVertex(vec23, 2);
				PolyAppend(TRUE);

				PolyVertexs(4);
				PolySetVertex(vec1,  0);
				PolySetVertex(vec12, 1);
//				PolySetVertex(vec23, 2);
				PolySetVertex(vec3,  3);
				PolySave();
			} else {
// 1 - 12 - 31, 12 - 2 - 23, 12 - 23 - 31, 31 - 23 - 3
//				PolySetVertex(vec1,  0);
				PolySetVertex(vec12, 1);
				PolySetVertex(vec31, 2);
				PolyAppend(TRUE);

				PolySetVertex(vec12, 0);
				PolySetVertex(vec2,  1);
				PolySetVertex(vec23, 2);
				PolyAppend(TRUE);

				PolySetVertex(vec12, 0);
				PolySetVertex(vec23, 1);
				PolySetVertex(vec31, 2);
				PolyAppend(TRUE);

				PolySetVertex(vec31, 0);
				PolySetVertex(vec23, 1);
				PolySetVertex(vec3,  2);
				PolySave();
			}
		}
	}
}

function Puff4()
{
	var vec1,vec2, vec3, vec4;
	var vec12, vec23, vec34, vec41, vec1234;
	var vec2341;
	var p, v, uv[2];
	var type;
	vec1 = PolyGetVertex(0);
	vec2 = PolyGetVertex(1);
	vec3 = PolyGetVertex(2);
	vec4 = PolyGetVertex(3);

	vec12 = PuffCenter(vec1, vec2);
	vec23 = PuffCenter(vec2, vec3);
	vec34 = PuffCenter(vec3, vec4);
	vec41 = PuffCenter(vec4, vec1);

//	if (typeof(vec12) == BOOLEAN | typeof(vec23) == BOOLEAN
//	  | typeof(vec34) == BOOLEAN | typeof(vec41) == BOOLEAN)
//		return;

	type = 0;
	if (typeof(vec12) != BOOLEAN) type += 8;
	if (typeof(vec23) != BOOLEAN) type += 4;
	if (typeof(vec34) != BOOLEAN) type += 2;
	if (typeof(vec41) != BOOLEAN) type += 1;

//print ("type=", type);

	if (type == 0) {
		return;
	} else if (type == 1) {
		PolyShiftVertex(3);
		vec12 = vec41;
		type = 8;
	} else if (type == 2) {
		PolyShiftVertex(2);
		vec12 = vec34;
		type = 8;
	} else if (type == 3) {
		PolyShiftVertex(2);
		vec12 = vec34;
		vec23 = vec41;
		type = 12;
	} else if (type == 4) {
		PolyShiftVertex(1);
		vec12 = vec23;
		type = 8;
	} else if (type == 5) {
		PolyShiftVertex(1);
		vec12 = vec23;
		vec34 = vec41;
		type = 10;
	} else if (type == 6) {
		PolyShiftVertex(1);
		vec12 = vec23;
		vec23 = vec34;
		type = 12;
	} else if (type == 7) {
		PolyShiftVertex(1);
		vec12 = vec23;
		vec23 = vec34;
		vec34 = vec41;
		type = 14;
	} else if (type == 8) {
	} else if (type == 9) {
		PolyShiftVertex(3);
		vec23 = vec12;
		vec12 = vec41;
		type = 12;
	} else if (type == 10) {
	} else if (type == 11) {
		PolyShiftVertex	(2);
//		vec12 = vec34;
//		vec23 = vec41;
//		vec34 = vec12;
		vec23 = vec41;
		vec41 = vec12;
		vec12 = vec34;
		vec34 = vec41;
		type = 14;
	} else if (type == 12) {
	} else if (type == 13) {
		PolyShiftVertex	(3);
		vec34 = vec23;
		vec23 = vec12;
		vec12 = vec41;
		type = 14;
	} else if (type == 14) {
	} else if (type == 15) {
		vec1234 = PuffCenter(vec12, vec34);
		vec2341 = PuffCenter(vec23, vec41);
		if (typeof(vec1234) == BOOLEAN | typeof(vec2341) == BOOLEAN)
			return;
		Mapping(vec1234, uv);
		vec1234 = Vertex((Position(vec1234) + Position(vec2341))*0.5,
				 (Vector(vec1234) + Vector(vec2341))*0.5, uv[0], uv[1]);

//		PolySetVertex(vec1,    0);
		PolySetVertex(vec12,   1);
		PolySetVertex(vec1234, 2);
		PolySetVertex(vec41,   3);
		PolyAppend(TRUE);

		PolySetVertex(vec12,   0);
		PolySetVertex(vec2,    1);
		PolySetVertex(vec23,   2);
		PolySetVertex(vec1234, 3);
		PolyAppend(TRUE);

		PolySetVertex(vec41,   0);
		PolySetVertex(vec1234, 1);
		PolySetVertex(vec34,   2);
		PolySetVertex(vec4,    3);
		PolyAppend(TRUE);

		PolySetVertex(vec1234, 0);
		PolySetVertex(vec23,   1);
		PolySetVertex(vec3,    2);
		PolySetVertex(vec34,   3);
		PolySave();
	}

//print ("->", type, "\n");


	vec1 = PolyGetVertex(0);
	vec2 = PolyGetVertex(1);
	vec3 = PolyGetVertex(2);
	vec4 = PolyGetVertex(3);

	if (type == 8) {
		PolyVertexs(3);
		PolySetVertex(vec1,  0);
		PolySetVertex(vec12, 1);
		PolySetVertex(vec4,  2);
		PolyAppend(TRUE);

		PolySetVertex(vec12, 0);
		PolySetVertex(vec3,  1);
		PolySetVertex(vec4,  2);
		PolyAppend(TRUE);

		PolySetVertex(vec12, 0);
		PolySetVertex(vec2,  1);
		PolySetVertex(vec3,  2);
		PolySave();
	} else if (type == 10) {
		PolySetVertex(vec1,  0);
		PolySetVertex(vec12, 1);
		PolySetVertex(vec34, 2);
		PolySetVertex(vec4,  3);
		PolyAppend(TRUE);

		PolySetVertex(vec12, 0);
		PolySetVertex(vec2,  1);
		PolySetVertex(vec3,  2);
		PolySetVertex(vec34, 3);
		PolySave();
	} else if (type == 12) {
		PolyVertexs(3);

		PolySetVertex(vec1,  0);
		PolySetVertex(vec12, 1);
		PolySetVertex(vec4,  2);
		PolyAppend(TRUE);

		PolySetVertex(vec12, 0);
		PolySetVertex(vec2,  1);
		PolySetVertex(vec23, 2);
		PolyAppend(TRUE);

		PolySetVertex(vec12, 0);
		PolySetVertex(vec23, 1);
		PolySetVertex(vec4,  2);
		PolyAppend(TRUE);

		PolySetVertex(vec23, 0);
		PolySetVertex(vec3,  1);
		PolySetVertex(vec4,  2);
		PolySave();
	} else if (type == 14) {
		PolySetVertex(vec1,  0);
		PolySetVertex(vec12, 1);
		PolySetVertex(vec34, 2);
		PolySetVertex(vec4,  3);
		PolyAppend(TRUE);

		PolyVertexs(3);

		PolySetVertex(vec12, 0);
		PolySetVertex(vec2,  1);
		PolySetVertex(vec23, 2);
		PolyAppend(TRUE);

		PolySetVertex(vec12, 0);
		PolySetVertex(vec23,  1);
		PolySetVertex(vec34, 2);
		PolyAppend(TRUE);

		PolySetVertex(vec23, 0);
		PolySetVertex(vec3,  1);
		PolySetVertex(vec34, 2);
		PolySave();
	}
}

function PuffPolygons()
{
	var	i, polys, vers;

	polys = SelectPolygons();
	PolyLoadInit();
	for (i = 0; i < polys; i++) {
		vers = PolyLoad();
		vers = PolyVertexs();
		if (PolyType() ==  POLY_SHADE | PolyType() == POLY_UVSHADE) {
			if (vers == 3) {
				Puff3();
			} else if (vers == 4) {
				Puff4();
			} else {
				Message("5角形以上の面があります。");
			}
		}
	}
	Update( CLEAR );
}

MenuPosition(
	Menu( " 編集(&E)",
		"平行移動(&M)	M",	Move,SelectCheck,
		"回転(&R)",			Rotate,SelectCheck,
		"拡大縮小(&S)",		Scale,SelectCheck,
		"-------------",	SEPARATE_MENU,
		"削除(&D)	DEL",	Delete,SelectCheck,
		"同一面削除(&U)",	DeleteSamePolygons,SelectCheck,
		"-------------",	SEPARATE_MENU,
		"複写(&C)",			Copy,SelectCheck,
		"ｸﾞﾘｯﾄﾞ複写(&G)",	GridCopy,SelectCheck,
		"ﾐﾗｰ複写(&M)",		Mirr,SelectCheck,
		"-------------",	SEPARATE_MENU,
		"面方向統一   ",	UnityPoly,SelectCheck,
		"面方向反転   ",	InversePoly,SelectCheck,
		"面二重化     ",	DuplicatePolygon,SelectCheck,
		"-------------",	SEPARATE_MENU,
		"面ｽﾑｰｼﾞﾝｸﾞ   ",	PuffPolygons,SelectCheck,
		"面分割       	B",	Separate,SelectCheck,
		"面合成       	J",	Joint,SelectCheck,
		"面自動分割",		Calipoly,SelectCheck,
		"面切断(&Z)",		Zante,SelectCheck
	), Menu_edit
);

