//------------------------------------------------------------------------------
// 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 STATIC_DEFORMED_MESH_COLLISION_H_
#define STATIC_DEFORMED_MESH_COLLISION_H_

#include <Collision/System/StaticCollisionLeaf.h>
#include <Geometry/Mesh/DeformedMeshGeometry.h>

namespace Lamp{

//------------------------------------------------------------------------------
/**
 * 静的変形メッシュコリジョン
 */
class StaticDeformedMeshCollision : public StaticCollisionLeaf{
friend class CollisionScene;
public:
	//--------------------------------------------------------------------------
	// 交差
	//--------------------------------------------------------------------------
	/**
	 * 球交差
	 * @param result 交差結果
	 * @param sphere 球
	 * @param collisionMask コリジョンマスク
	 */
	virtual void intersection(IntersectionResult* result, const Sphere& sphere,
		u_int collisionMask = 0xffffffff);

	/**
	 * 球コリジョン交差
	 * @param result 交差結果
	 * @param sphere 球コリジョン
	 * @param collisionMask コリジョンマスク
	 */
	virtual void intersection(IntersectionResult* result,
		StaticSphereCollision* sphere, u_int collisionMask = 0xffffffff);

	//--------------------------------------------------------------------------
	// メッシュ
	//--------------------------------------------------------------------------
	/**
	 * メッシュの取得
	 * @return ローカル座標のメッシュ
	 */
	virtual const DeformedMeshGeometry& getMesh() const{ return mesh_; }

	/**
	 * ワールドメッシュの取得
	 *
	 * ワールドメッシュの取得を行った時点でメッシュがワールド座標に変換される
	 * @return ワールド座標のメッシュ
	 */
	virtual const DeformedMeshGeometry& getWorldMesh();

	//--------------------------------------------------------------------------
	// トライアングル
	//--------------------------------------------------------------------------
	/**
	 * トライアングル数の設定
	 * @param triangleCount トライアングル数
	 */
	virtual void setTriangleCount(int triangleCount){
		mesh_.setTriangleCount(triangleCount);
		worldMesh_.setTriangleCount(triangleCount);
		setChanged(true);
	}

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

	//--------------------------------------------------------------------------
	/**
	 * トライアングルの設定
	 * @param index インデックス
	 * @param triangle トライアングル
	 */
	virtual void setTriangle(int index, const Triangle& triangle){
		mesh_.setTriangle(index, triangle);
		setChanged(true);
	}

	/**
	 * トライアングルの取得
	 * @param index インデックス
	 * @return トライアングル
	 */
	virtual const Triangle& getTriangle(int index) const{
		return mesh_.getTriangle(index);
	}

	//--------------------------------------------------------------------------
	// バウンディング
	//--------------------------------------------------------------------------
	/**
	 * バウンディングの算出
	 */
	virtual void calculateBounding(){
		mesh_.calculateBounding();
		setChanged(true);
	}

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

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

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

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

	//--------------------------------------------------------------------------
	// コピー
	//--------------------------------------------------------------------------
	/**
	 * コピー
	 * @return コピーされたコリジョンオブジェクト
	 */
	virtual CollisionObject* copy() const{
		return copyStaticDeformedMeshCollision();
	}

	/**
	 * コリジョンリーフのコピー
	 * @return コピーされたコリジョンリーフ
	 */
	virtual CollisionLeaf* copyCollisionLeaf() const{
		return copyStaticDeformedMeshCollision();
	}

	/**
	 * 静的コリジョンリーフのコピー
	 * @return コピーされた静的コリジョンリーフ
	 */
	virtual StaticCollisionLeaf* copyStaticCollisionLeaf() const{
		return copyStaticDeformedMeshCollision();
	}

	/**
	 * 静的変形メッシュコリジョンのコピー
	 * @return コピーされた静的変形メッシュコリジョン
	 */
	virtual StaticDeformedMeshCollision*
		copyStaticDeformedMeshCollision() const;

	//--------------------------------------------------------------------------
	// RTTI
	//--------------------------------------------------------------------------
	/**
	 * 静的変形メッシュコリジョンかどうか
	 * @return 静的変形メッシュコリジョンならtrue
	 */
	virtual bool isStaticDeformedMeshCollision() const{ return true; }

protected:
	//--------------------------------------------------------------------------
	// 生成、破棄
	//--------------------------------------------------------------------------
	/**
	 * コンストラクタ
	 * @param name 名前
	 * @param scene シーン
	 */
	StaticDeformedMeshCollision(const String& name, CollisionScene* scene);

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

	//--------------------------------------------------------------------------
	// 走査
	//--------------------------------------------------------------------------
	/**
	 * 走査
	 * @param parentMatrix 親行列
	 * @param parentEnabled 親が有効か
	 * @param parentScaled 親がスケールを使用しているか
	 * @param parentChanged 親に変更があったか
	 */
	virtual void traverseImplement(const Matrix34& parentMatrix,
		bool parentEnabled, bool parentScaled, bool parentChanged);

private:
	//--------------------------------------------------------------------------
	// メッシュ
	DeformedMeshGeometry mesh_;
	// ワールドメッシュ
	DeformedMeshGeometry worldMesh_;
	// ワールドメッシュ変更フラグ
	bool worldMeshChanged_;

};

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