/*
	AramakiOnline
	Copyright (C) 2008 superbacker

	This program is free software; you can redistribute it and/or modify it under the terms
	of the GNU General Public License as published by the Free Software Foundation;
	either version 3 of the License, or (at your option) any later version.

	This program is distributed in the hope that it will be useful, but WITHOUT ANY
	WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
	FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

	You should have received a copy of the GNU General Public License along with this
	program. If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef FACE_H_
#define FACE_H_

#include "Point3d.h"
#include <vector>

//頂点配列
typedef std::vector<Point3d> Vertexes;

//面
struct Face {
	//頂点
	Vertexes vertexes;
	//面法線
	Point3d normalVector;

	//線分と当たり判定をとる
	inline bool collide(const Point3d &lineStart,const Point3d &lineEnd,Point3d &crossPoint) const {
		Point3d u,cp;
		double top,bottom,t;

		//直線の方程式よりuを求める
		//cp=lineStart+tu
		u=lineEnd-lineStart;
		top=normalVector.x*(vertexes[0].x-lineStart.x)+normalVector.y*(vertexes[0].y-lineStart.y)+normalVector.z*(vertexes[0].z-lineStart.z);

		//内積
		bottom=normalVector.dot(u);

		//平行判定
		if (bottom==0.0) return false;

		//tを求める
		t=top/bottom;

		//0=<t=<1以外の場合、交差していない
		if (t<0.0||t>1.0) return false;

		//面と線の交点を求める
		cp=lineStart+u*t;

		//内外判定
		for (size_t i=0;i<vertexes.size();++i) {
			Point3d normal;
			double n;

			//内積で内外判定
			normal.normalVector(cp,vertexes[i],vertexes[(i+1)%vertexes.size()]);
			n=normal.dot(normalVector);

			//法線の向きとちがうので外側
			if (n<0.0) return false;
		}

		//法線向きがすべて同じなので内側
		crossPoint=cp;

		return true;
	}
};

#endif /* FACE_H_ */
