//------------------------------------------------------------------------------
// Lamp : Open source game middleware
// Copyright (C) 2004  Junpei Ohtani ( Email : junpee@users.sourceforge.jp )
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//------------------------------------------------------------------------------

/** @file
 * 変形メッシュジオメトリヘッダ
 * @author Junpee
 */

#ifndef DEFORMED_MESH_GEOMETRY_H_
#define DEFORMED_MESH_GEOMETRY_H_

#include <Geometry/Mesh/MeshGeometry.h>

namespace Lamp{

//------------------------------------------------------------------------------
/**
 * 変形メッシュジオメトリ
 */
class DeformedMeshGeometry : public MeshGeometry{
public:
	//--------------------------------------------------------------------------
	// 生成、破棄
	//--------------------------------------------------------------------------
	/**
	 * コンストラクタ
	 */
	DeformedMeshGeometry();

	/**
	 * コピーコンストラクタ
	 * @param copy コピー元
	 */
	explicit DeformedMeshGeometry(const DeformedMeshGeometry& copy);

	/**
	 * 代入コピー
	 * @param copy コピー元
	 * @return コピーされた変形メッシュジオメトリ
	 */
	virtual const DeformedMeshGeometry& operator =(
		const DeformedMeshGeometry& copy);

	/**
	 * デストラクタ
	 */
	virtual ~DeformedMeshGeometry();

	//--------------------------------------------------------------------------
	// 交差
	//--------------------------------------------------------------------------
	/**
	 * 球交差
	 * @param sphere 交差判定する球
	 * @return 交差していればtrue
	 */
	virtual bool intersect(const Sphere& sphere) const;

	/**
	 * 球交差
	 * @param sphere 交差判定する球
	 * @param result 交差結果
	 */
	virtual void intersect(
		IntersectionResult* result, const Sphere& sphere) const;

	/**
	 * 球バウンディング交差
	 * @param sphere 交差判定する球
	 * @return バウンディングと交差していればtrue
	 */
	virtual bool intersectBounding(const Sphere& sphere) const;

	/**
	 * 球メッシュ交差
	 * @param sphere 交差判定する球
	 * @return メッシュと交差していればtrue
	 */
	virtual bool intersectMesh(const Sphere& sphere) const;

	/**
	 * 球メッシュ交差
	 * @param sphere 交差判定する球
	 * @param result 交差結果
	 */
	virtual void intersectMesh(
		IntersectionResult* result, const Sphere& sphere) const;

	//--------------------------------------------------------------------------
	// トライアングル
	//--------------------------------------------------------------------------
	/**
	 * トライアングル数の設定
	 * @param triangleCount トライアングル数
	 */
	virtual void setTriangleCount(int triangleCount);

	/**
	 * トライアングル数の取得
	 * @return トライアングル数
	 */
	virtual int getTriangleCount() const{ return triangleCount_; }

	//--------------------------------------------------------------------------
	/**
	 * トライアングルの設定
	 * @param index インデックス
	 * @param triangle トライアングル
	 */
	virtual void setTriangle(int index, const Triangle& triangle){
		Assert((index >= 0) && (index < triangleCount_));
		triangles_[index] = triangle;
	}

	/**
	 * トライアングルの取得
	 * @param index インデックス
	 * @return トライアングル
	 */
	virtual const Triangle& getTriangle(int index) const{
		Assert((index >= 0) && (index < triangleCount_));
		return triangles_[index];
	}

	//--------------------------------------------------------------------------
	// バウンディング
	//--------------------------------------------------------------------------
	/**
	 * バウンディングの算出
	 */
	virtual void calculateBounding();

	//--------------------------------------------------------------------------
	/**
	 * バウンディングボックスの設定
	 * @param boundingBox バウンディングボックス
	 */
	virtual void setBoundingBox(const AxisAlignedBox& boundingBox){
		boundingBox_ = boundingBox;
	}

	/**
	 * バウンディングボックスの取得
	 * @return バウンディングボックス
	 */
	virtual const AxisAlignedBox& getBoundingBox() const{ return boundingBox_; }

	//--------------------------------------------------------------------------
	/**
	 * バウンディングスフィアの設定
	 * @param boundingSphere バウンディングスフィア
	 */
	virtual void setBoundingSphere(const Sphere& boundingSphere){
		boundingSphere_ = boundingSphere;
	}

	/**
	 * バウンディングスフィアの取得
	 * @return バウンディングスフィア
	 */
	virtual const Sphere& getBoundingSphere() const{
		return boundingSphere_;
	}

protected:
	//--------------------------------------------------------------------------
	/**
	 * 変形メッシュジオメトリデータのコピー
	 * @param copy コピー元
	 */
	virtual void copyDeformedMeshGeometryData(const DeformedMeshGeometry& copy);

private:
	//--------------------------------------------------------------------------
	// バウンディングボックス
	AxisAlignedBox boundingBox_;
	// バウンディングスフィア
	Sphere boundingSphere_;
	// トライアングル配列
	Triangle* triangles_;
	// トライアングル数
	int triangleCount_;
};

//------------------------------------------------------------------------------
} // End of namespace Lamp
#endif // End of DEFORMED_MESH_GEOMETRY_H_
//------------------------------------------------------------------------------
