///////////////////////////////////////////////////////////////////////////////
//  S3D.h

#pragma once

#include <math.h>
#include "3DDefine.h"

struct SMatrix;

struct S3D {
	float	fX, fY, fZ;

	S3D(void);
	S3D(float fX0, float fY0, float fZ0);

	bool operator==(const S3D& Obj) const;
	bool operator!=(const S3D& Obj) const;

	bool operator<(const S3D& Obj) const;
	bool operator>(const S3D& Obj) const;

	S3D& operator*=(float f);
	S3D& operator/=(float f);

	S3D& operator+=(const S3D& a);
	S3D& operator-=(const S3D& a);
	const S3D& operator*=(const S3D& Obj);

	S3D& operator*=(const SMatrix& m);
	S3D operator*(const SMatrix& m) const;

	S3D operator*(float f) const;
	S3D operator/(float f) const;

	S3D operator+(const S3D& a) const;
	S3D operator-(const S3D& a) const;
	S3D operator*(const S3D& Data) const;

	friend S3D operator*(float f, const S3D& Pos);

	S3D operator-() const;

	/// @brief 各要素への添え字アクセスを提供する
	/// @param idx 添え字
	/// @attension idxの範囲は0〜2です。これを超えるとアサーション起こすようにしています
	float operator[](size_t idx)const;

	//
	void	Set(float fX0, float fY0, float fZ0);

	//
	S3D		GetXZOnly() const;

	//
	float	Length() const;
	float	Length2() const;

	static float	Distance(const S3D& pos1, const S3D& pos2);
	static float	Distance2(const S3D& pos1, const S3D& pos2);

	static S3D	Sub(const S3D& a, const S3D& b);

	static S3D		CrossProduct(const S3D& vec1, const S3D& vec2);
	static float	DotProduct(const S3D& vec1, const S3D& vec2);

	S3D		GetOpenGLPos() const;

	// FromからToに回転する回転軸と角度（ラジアン）を求める
	// ベクトルは正規化されているものとする
	static bool		CalcRotateAxisAndAngle(S3D& RotateAxis, float& Angle, const S3D& FromVector, const S3D& ToVector);

	// 正規化
	void	Normalize();
	S3D		GetNormalize() const;

	//
	S3D		MulMatrixRot(const SMatrix& m) const;

	// ラジアン変換
	S3D		GetRadToDeg() const;
	S3D		GetDegToRad() const;

	// 座標系変換
	S3D		GetOpenGL() const;
};

