#pragma once
#include <FK/FK.h>
#include <set>

class fkut_OBB {
private:
	static set<fkut_OBB *>	instanceList;
	map<fkut_OBB *, int>	nearestArray;
protected:
	fk_Vector	m_Pos;					// 位置
	fk_Vector	m_NormaDirect[3];		// 方向ベクトル
	double		m_fLength[3], sphRad;	// 各軸方向の長さ＆球での刈り込み用半径

	fk_Model	*ref_model;

	fk_Vector	backVec[15];			// 分離軸は15本

	double		elemD;

	double		LenSegOnSeparateAxis(fk_Vector *Sep, fk_Vector *e1, fk_Vector *e2, fk_Vector *e3 = NULL);

	fk_Vector	GetDirect(int axis);	// 指定軸番号の方向ベクトルを取得
	double		GetLen_W(int axis);     // 指定軸方向の長さを取得
	fk_Vector	GetPos_W(void);         // 位置を取得

	bool		Update(void);

public:
	fkut_OBB(void);
	~fkut_OBB(void);

	void		setDivDist(double);						// 動物体判定時の精度を設定(小さくしすぎると激重)
	void		setBlockSize(double, double, double);	// サイズ設定
	void		setModel(fk_Model *);					// 位置、姿勢、スケールのベースとなるモデルのセット

	fk_Vector	checkVSPoint(fk_Vector pos);			// 点との判定（普通使わない）

				// 球体との判定（座標、半径、戻しベクトル受け）
	bool		checkVSSphere(const fk_Vector &pos, double rad, fk_Vector &backV);
				// 動く球体との判定（座標、半径、球の移動ベクトル、戻しベクトル受け）
	bool		checkVSMovingSphere(const fk_Vector &pos, double rad, const fk_Vector &spd, fk_Vector &backV);
				// OBB同士の判定（相手のOBB、戻しベクトル受け）
	bool		checkVSOBB(fkut_OBB &other, fk_Vector &backV);
				// 動くOBBとの判定（相手のOBB、相手OBBの移動ベクトル、戻しベクトル受け）
	bool		checkVSMovingOBB(fkut_OBB &other, fk_Vector &spd, fk_Vector &backV);
};

class fkut_Capsule {
private:
	fk_Vector	p, q;
	double		r, len;

	fk_Model	*ref_model;

	bool		Update(void);

public:
	void setCapsuleSize(double, double);	// カプセルのサイズ（半径、長さ）
	void setModel(fk_Model *);				// 位置、姿勢のベースとなるモデルのセット
	// ref_modelの中心座標をp、p+モデルの向き(getVec()で得られる方向ベクトル)*lenをqとする

	// カプセル同士の判定（相手のカプセル、戻しベクトル受け）
	bool checkVSCapsule(fkut_Capsule &other, fk_Vector *revVec);
};
