#pragma once

#include "../Shape.h"

#include <C2/lm/vector2.h>
#include <C2/lm/vector3.h>
#include <C2/lm/range3.h>


namespace lib_geo
{


//! 3Dの幾何学演算
class Geom3d
{
public:
	typedef lm::vec2f   vec2f;
	typedef lm::vec3f   vec3f;
	typedef lm::range3f range3f;

public:

	// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
	// intersect

	// 線分対平面の交差
	static bool Intersect_Plane_Segment( const Plane& i_plane , const Segment& i_segment );
	static bool Intersect_Plane_Segment( const Plane& i_plane , const Segment& i_segment , vec3f& intersect_pos );
	static bool Intersect_Plane_Segment( const vec3f& plane_normal , const vec3f& plane_point , const vec3f& e0 , const vec3f& e1 );
	static bool Intersect_Plane_Segment( const vec3f& plane_normal , const vec3f& plane_point , const vec3f& e0 , const vec3f& e1 , vec3f& intersect_pos );

	// 線分対三角形の交差
	static bool Intersect_Triangle_Segment( const Triangle& i_triangle , const Segment& i_segment );
	static bool Intersect_Triangle_Segment( const Triangle& i_triangle , const Segment& i_segment , vec3f& intersect_pos );
	static bool Intersect_Triangle_Segment( const vec3f& t0 , const vec3f& t1 , const vec3f& t2 , const vec3f& e0 , const vec3f& e1 );
	static bool Intersect_Triangle_Segment( const vec3f& t0 , const vec3f& t1 , const vec3f& t2 , const vec3f& e0 , const vec3f& e1 , vec3f& intersect_pos );

	// 三角形対三角形の交差
	static bool Intersect_Triangle_Triangle( const vec3f& t00 , const vec3f& t01 , const vec3f& t02 , const vec3f& t10 , const vec3f& t11 , const vec3f& t12 );

	// 線分対AABBの交差
	static bool Intersect_AABB_Segment( const range3f& aabb , const vec3f& e0 , const vec3f& e1 );

	// 線分同士の擬似交差判定
	static bool Intersect_Segments( const vec3f& a0 , const vec3f& a1 , const vec3f& b0 , const vec3f& b1 , vec3f& inter_pos );


	// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
	// closest point

	// 線分[e0--e1]上で、pに最も近い位置を求める
	static vec3f Closest_Segment_Point( const vec3f& e0 , const vec3f& e1 , const vec3f& p );

	// 三角形[t0--t1--t2]上で、pに最も近い位置を求める
	static vec3f Closest_Triangle_Point( const vec3f& t0 , const vec3f& t1 , const vec3f& t2 , const vec3f& p );


	// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

	// 重心座標の取得
	static void Get_BaryCentCoord( const Triangle& i_triangle , const vec3f& p , float& u , float& v , float& w );
	static void Get_BaryCentCoord( const Triangle& i_triangle , const vec3f& p , vec3f& bary_coord );
	static void Get_BaryCentCoord( const vec3f& t0 , const vec3f& t1 , const vec3f& t2 , const vec3f& p , float& u , float& v , float& w );
	static void Get_BaryCentCoord( const vec3f& t0 , const vec3f& t1 , const vec3f& t2 , const vec3f& p , vec3f& bary_coord );


	// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

	static float Areasize_Triangle( const vec3f& t0 , const vec3f& t1 , const vec3f& t2 );
};


}
