//---------------------------------------------------------------------------
//
//   MQ3DLib.h      Copyright(C) 1999-2000, O.Mizno
//
//    　ちょっと便利な関数集。
//
//---------------------------------------------------------------------------

#ifndef MQ3DLIB_H
#define MQ3DLIB_H

#include <math.h>

// float型浮動小数点演算関数に対応していないC++Builder5用対策
#ifdef __BORLANDC__
#define sqrtf sqrt
#endif



// 円周率π
#ifndef PI
	#define PI 3.1415926536f
#endif

// 弧度(0から360)からラジアン(0から2π)へ変換
#ifndef RAD
	#define RAD(_x) ((_x)/180.0f*PI)
#endif

// ラジアン(0から2π)から弧度(0から360)へ変換
#ifndef DEG
	#define DEG(_x) ((_x)/PI*180.0f)
#endif

// ベクトルのサイズの２乗
inline float GetNorm(const MQPoint& p)
{
	return p.x*p.x + p.y*p.y + p.z*p.z;
}

// ベクトルのサイズ
inline float GetSize(const MQPoint& p)
{
	return sqrtf(p.x*p.x + p.y*p.y + p.z*p.z);
}

// ベクトルの正規化
inline MQPoint Normalize(const MQPoint& p) 
{
	float s = GetSize(p);
	if(s == 0.0f)
		return MQPoint(0,0,0);
	return p / s;
}

// 内積の値を得る
inline float GetInnerProduct(const MQPoint& pa, const MQPoint& pb)
{
	return pa.x * pb.x + pa.y * pb.y + pa.z * pb.z; 
}

// 外積ベクトルを得る
inline MQPoint GetCrossProduct(const MQPoint& v1, const MQPoint& v2)
{
	return MQPoint(
		v1.y * v2.z - v1.z * v2.y,
		v1.z * v2.x - v1.x * v2.z,
		v1.x * v2.y - v1.y * v2.x);
}

inline MQPoint GetExteriorProduct(const MQPoint& v1, const MQPoint& v2)
{
	return GetCrossProduct(v1, v2); 
}

// 3点からなる面の法線を得る
MQPoint GetNormal(const MQPoint& p0, const MQPoint& p1, const MQPoint& p2);

// 4点からなる面の法線を得る
MQPoint GetQuadNormal(const MQPoint& p0, const MQPoint& p1, const MQPoint& p2, const MQPoint& p3);

// 2ベクトルの交差する角度をラジアン単位の0からπまでの値で得る
float GetCrossingAngle(const MQPoint& v1, const MQPoint& v2);

// 反対向きの面が存在するかどうかを調べる
// 存在していればその面のインデックスを、なければ-1を返す
int SearchInvertedFace(MQObject obj, int faceindex, int start=-1, int end=-1);


// オブジェクト中の法線を計算するクラス
class MQObjNormal
{
protected:
	MQPoint *normal;
public:
	MQObjNormal(MQObject obj);
	virtual ~MQObjNormal();

	inline MQPoint& Get(int face_index, int pt_index) {
		return normal[face_index*4 + pt_index];
	}
};


// MQObjEdgeクラス内で使用されるエッジ対情報
class MQObjEdgePair
{
public:
	int face;
	int line;

	inline MQObjEdgePair() { face = line = -1; }
	inline MQObjEdgePair(int f, int l) { face = f; line = l; }
	inline MQObjEdgePair& operator = (const MQObjEdgePair& r)
		{ face=r.face; line=r.line; return *this; }
};

typedef MQObjEdgePair MQObjEdgePairFace[4];


// オブジェクトのエッジ対管理クラス
class MQObjEdge
{
protected:
	int m_face;
	MQObject m_obj;
	MQObjEdgePairFace *m_pair;
public:
	MQObjEdge(MQObject obj);
	virtual ~MQObjEdge();

	bool getPair(int face_index, int line_index, int& pair_face, int& pair_line);
};


#endif //MQ3DLIB_H