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

#include <Graphics/Scene/SceneObject.h>
#include <Graphics/System/GraphicsDeviceObjectHolder.h>
#include <Core/Container/ArrayList.h>
#include <Graphics/Mesh/Mesh.h>// PrimitiveTypeを分離すればはずせる

namespace Lamp{

class Mesh;

//------------------------------------------------------------------------------
/**
 * メッシュデータ
 */
class MeshData : public SceneObject , public GraphicsDeviceObjectHolder{
friend class SceneObjectManagerTemplate<MeshData>;
friend class MeshDataManager;
friend class Mesh;
public:
	/**
	 * リファレンスカウントの取得
	 * @return リファレンスカウント
	 */
	virtual int getReferenceCount() const{ return parents_.getCount(); }

	//--------------------------------------------------------------------------
	/**
	 * コピー
	 */
	virtual MeshData* copy() const;

	/**
	 * 破棄
	 * @param meshData 破棄するメッシュデータ
	 * @return 破棄したオブジェクト数
	 */
	static int destroy(MeshData* meshData);

	//--------------------------------------------------------------------------
	// 親
	//--------------------------------------------------------------------------
	/**
	 * 親のサイズ取得
	 * @return 親のサイズ
	 */
	virtual int getParentCount() const{ return parents_.getCount(); }

	/**
	 * 親の取得
	 * @param index 親のインデックス
	 * @return 親
	 */
	virtual Mesh* getParent(int index) const{
		Assert((index >= 0) && (index < getParentCount()));
		return parents_.get(index);
	}

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

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

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

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

	//--------------------------------------------------------------------------
	/**
	 * バウンディング変更フラグの取得
	 * @return バウンディング変更フラグ
	 */
	virtual bool isBoundingChanged() const{ return boundingChanged_; }

	/**
	 * バウンディング変更フラグのクリア
	 */
	virtual void clearBoundingChanged(){ boundingChanged_ = false; }

	//--------------------------------------------------------------------------
	// プリミティブタイプ
	//--------------------------------------------------------------------------
	/**
	 * プリミティブタイプの設定
	 * @param primitiveType プリミティブタイプ
	 */
	virtual void setPrimitiveType(Mesh::PrimitiveType primitiveType);

	/**
	 * プリミティブタイプの取得
	 * @return プリミティブタイプ
	 */
	virtual Mesh::PrimitiveType getPrimitiveType() const{
		return primitiveType_;
	}

	/**
	 * プリミティブカウントの取得
	 * @return プリミティブカウント
	 */
	virtual int getPrimitiveCount() const;

	/**
	 * 三角の取得
	 * @param index プリミティブインデックス
	 * @return 三角
	 */
	virtual Triangle getTriangle(int index) const;

	//--------------------------------------------------------------------------
	// インデックス
	//--------------------------------------------------------------------------
	/**
	 * 頂点インデックスを持つかどうか
	 * @return 頂点インデックスを持つならtrue
	 */
	virtual bool hasVertexIndices() const{
		return Mesh::primitiveTypeHasIndex(primitiveType_);
	}

	/**
	 * 頂点インデックス数の設定
	 * @param vertexIndexCount 頂点インデックス数
	 */
	virtual void setVertexIndexCount(int vertexIndexCount);

	/**
	 * 頂点インデックス数の取得
	 * @return 頂点インデックス数
	 */
	virtual int getVertexIndexCount() const{ return vertexIndexCount_; }

	/**
	 * 頂点インデックスの設定
	 * @param index インデックス
	 * @param vertexIndex 頂点インデックス
	 */
	virtual void setVertexIndex(int index, u_short vertexIndex){
		Assert(hasVertexIndices());
		Assert((index >= 0) && (index < vertexIndexCount_));
		vertexIndexArray_[index] = vertexIndex;
		indexBufferChanged_ = true;
	}

	/**
	 * 頂点インデックスの取得
	 * @param index インデックス
	 * @return 頂点インデックス
	 */
	virtual u_short getVertexIndex(int index) const{
		Assert(hasVertexIndices());
		Assert((index >= 0) && (index < vertexIndexCount_));
		return vertexIndexArray_[index];
	}

	/**
	 * 頂点インデックス配列の取得
	 * @return 頂点インデックス配列
	 */
	virtual const u_short* getVertexIndexArray(){ return vertexIndexArray_; }

	//--------------------------------------------------------------------------
	// 頂点数
	//--------------------------------------------------------------------------
	/**
	 * 頂点数の設定
	 * @param vertexCount 頂点数
	 */
	virtual void setVertexCount(int vertexCount);

	/**
	 * 頂点数の取得
	 * @return 頂点数
	 */
	virtual int getVertexCount() const{ return vertexCount_; }

	//--------------------------------------------------------------------------
	// 位置
	//--------------------------------------------------------------------------
	/**
	 * 位置の設定
	 * @param index インデックス
	 * @param position 位置
	 */
	virtual void setPosition(int index, const Vector3& position){
		Assert((index >= 0) && (index < vertexCount_));
		positions_[index] = position;
		vertexBufferChanged_ = true;
	}

	/**
	 * 位置の取得
	 * @param index インデックス
	 * @return 位置
	 */
	virtual const Vector3& getPosition(int index) const{
		Assert((index >= 0) && (index < vertexCount_));
		return positions_[index];
	}

	/**
	 * 位置配列の取得
	 * @return 位置配列
	 */
	virtual const Vector3* getPositionArray() const{ return positions_; }

	//--------------------------------------------------------------------------
	// 法線
	//--------------------------------------------------------------------------
	/**
	 * 法線を有効にするかどうか
	 * @param normalFlag trueなら法線が有効になる
	 */
	virtual void enableNormal(bool normalFlag);

	/**
	 * 法線が有効かどうか
	 * @return 法線が有効ならtrue
	 */
	virtual bool hasNormal() const{ return normalFlag_; }

	/**
	 * 法線の設定
	 * @param index インデックス
	 * @param normal 法線
	 */
	virtual void setNormal(int index, const Vector3& normal){
		Assert(hasNormal());
		Assert((index >= 0) && (index < vertexCount_));
		normals_[index] = normal;
		vertexBufferChanged_ = true;
	}

	/**
	 * 法線の取得
	 * @param index インデックス
	 * @return 法線
	 */
	virtual const Vector3& getNormal(int index) const{
		Assert(hasNormal());
		Assert((index >= 0) && (index < vertexCount_));
		return normals_[index];
	}

	/**
	 * 法線配列の取得
	 * @return 法線配列
	 */
	virtual const Vector3* getNormalArray() const{ return normals_; }

	//--------------------------------------------------------------------------
	// カラー
	//--------------------------------------------------------------------------
	/**
	 * カラーを有効にするかどうか
	 * @param colorFlag trueならカラーが有効になる
	 */
	virtual void enableColor(bool colorFlag);

	/**
	 * カラーが有効かどうか
	 * @return カラーが有効ならtrue
	 */
	virtual bool hasColor() const{ return colorFlag_; }

	/**
	 * カラーの設定
	 * @param index インデックス
	 * @param color カラー
	 */
	virtual void setColor(int index, const Color4c& color){
		Assert(hasColor());
		Assert((index >= 0) && (index < vertexCount_));
		colors_[index] = color;
		vertexBufferChanged_ = true;
	}

	/**
	 * カラーの取得
	 * @param index インデックス
	 * @return カラー
	 */
	virtual const Color4c& getColor(int index) const{
		Assert(hasColor());
		Assert((index >= 0) && (index < vertexCount_));
		return colors_[index];
	}

	/**
	 * カラー配列の取得
	 * @return カラー配列
	 */
	virtual const Color4c* getColorArray() const{ return colors_; }

	//--------------------------------------------------------------------------
	// テクスチャ座標
	//--------------------------------------------------------------------------
	/**
	 * テクスチャ座標セット数の設定
	 * @param texCoordSetCount テクスチャ座標セット数
	 */
	virtual void setTexCoordSetCount(int texCoordSetCount);

	/**
	 * テクスチャ座標セット数の設定
	 * @return テクスチャ座標セット数
	 */
	virtual int getTexCoordSetCount() const{ return texCoordSetCount_; }

	//--------------------------------------------------------------------------
	/**
	 * テクスチャ座標タイプの設定
	 * @param texCoordSet テクスチャ座標セット
	 * @param texCoordType テクスチャ座標タイプ
	 */
	virtual void setTexCoordType(int texCoordSet, TexCoord::Type texCoordType);

	/**
	 * テクスチャ座標タイプの取得
	 * @param texCoordSet テクスチャ座標セット
	 * @return テクスチャ座標タイプ
	 */
	virtual TexCoord::Type getTexCoordType(int texCoordSet) const{
		Assert((texCoordSet >= 0) && (texCoordSet < texCoordSetCount_));
		return texCoordTypes_[texCoordSet];
	}

	/**
	 * テクスチャ座標タイプ配列の取得
	 * @return テクスチャ座標タイプ配列
	 */
	virtual const TexCoord::Type* getTexCoordTypeArray() const{
		return texCoordTypes_;
	}

	//--------------------------------------------------------------------------
	/**
	 * テクスチャ座標の設定
	 * @param index インデックス
	 * @param texCoordSet テクスチャ座標セット
	 * @param texCoord テクスチャ座標
	 * @param numTexCoord いくつのテクスチャ座標か
	 */
	virtual void setTexCoord(
		int index, int texCoordSet, const float* texCoord, int numTexCoord){
		Assert((index >= 0) && (index < vertexCount_));
		Assert((texCoordSet >= 0) && (texCoordSet < texCoordSetCount_));
		Assert(texCoordTypes_[texCoordSet] == numTexCoord);
		float* destination = texCoords_[texCoordSet] + (index * numTexCoord);
		std::memcpy(destination, texCoord, sizeof(float) * numTexCoord);
		vertexBufferChanged_ = true;
	}

	/**
	 * テクスチャ座標配列の取得
	 * @return テクスチャ座標配列
	 */
	virtual const float* const* getTexCoordArray() const{ return texCoords_; }

	/**
	 * テクスチャ座標配列の取得
	 * @param texCoordSet テクスチャ座標セット
	 * @return テクスチャ座標配列
	 */
	virtual const float* getTexCoordArray(int texCoordSet) const{
		Assert((texCoordSet >= 0) && (texCoordSet < texCoordSetCount_));
		return texCoords_[texCoordSet];
	}

	/**
	 * テクスチャ座標配列サイズの取得
	 * @param texCoordSet テクスチャ座標セット
	 * @return テクスチャ座標配列サイズ
	 */
	virtual int getTexCoordArraySize(int texCoordSet) const{
		Assert((texCoordSet >= 0) && (texCoordSet < texCoordSetCount_));
		return sizeof(float) * texCoordTypes_[texCoordSet] * vertexCount_;
	}

	//--------------------------------------------------------------------------
	/**
	 * 一次元テクスチャ座標の設定
	 * @param index インデックス
	 * @param texCoordSet テクスチャ座標セット
	 * @param texCoord 一次元テクスチャ座標
	 */
	virtual void setTexCoord1(
		int index, int texCoordSet, const TexCoord1& texCoord){
		Assert((index >= 0) && (index < vertexCount_));
		Assert((texCoordSet >= 0) && (texCoordSet < texCoordSetCount_));
		Assert(texCoordTypes_[texCoordSet] == TexCoord::type1);
		((TexCoord1*)texCoords_[texCoordSet])[index] = texCoord;
		vertexBufferChanged_ = true;
	}

	/**
	 * 一次元テクスチャ座標の取得
	 * @param index インデックス
	 * @param texCoordSet テクスチャ座標セット
	 * @return 一次元テクスチャ座標
	 */
	virtual const TexCoord1& getTexCoord1(int index, int texCoordSet) const{
		Assert((index >= 0) && (index < vertexCount_));
		Assert((texCoordSet >= 0) && (texCoordSet < texCoordSetCount_));
		Assert(texCoordTypes_[texCoordSet] == TexCoord::type1);
		return ((TexCoord1*)texCoords_[texCoordSet])[index];
	}

	/**
	 * 一次元テクスチャ座標配列の取得
	 * @param texCoordSet テクスチャ座標セット
	 * @return 一次元テクスチャ座標配列
	 */
	virtual const TexCoord1* getTexCoord1Array(int texCoordSet) const{
		Assert((texCoordSet >= 0) && (texCoordSet < texCoordSetCount_));
		Assert(texCoordTypes_[texCoordSet] == TexCoord::type1);
		return (TexCoord1*)texCoords_[texCoordSet];
	}

	//--------------------------------------------------------------------------
	/**
	 * 二次元テクスチャ座標の設定
	 * @param index インデックス
	 * @param texCoordSet テクスチャ座標セット
	 * @param texCoord 二次元テクスチャ座標
	 */
	virtual void setTexCoord2(
		int index, int texCoordSet, const TexCoord2& texCoord){
		Assert((index >= 0) && (index < vertexCount_));
		Assert((texCoordSet >= 0) && (texCoordSet < texCoordSetCount_));
		Assert(texCoordTypes_[texCoordSet] == TexCoord::type2);
		((TexCoord2*)texCoords_[texCoordSet])[index] = texCoord;
		vertexBufferChanged_ = true;
	}

	/**
	 * 二次元テクスチャ座標の取得
	 * @param index インデックス
	 * @param texCoordSet テクスチャ座標セット
	 * @return 二次元テクスチャ座標
	 */
	virtual const TexCoord2& getTexCoord2(int index, int texCoordSet) const{
		Assert((index >= 0) && (index < vertexCount_));
		Assert((texCoordSet >= 0) && (texCoordSet < texCoordSetCount_));
		Assert(texCoordTypes_[texCoordSet] == TexCoord::type2);
		return ((TexCoord2*)texCoords_[texCoordSet])[index];
	}

	/**
	 * 二次元テクスチャ座標配列の取得
	 * @param texCoordSet テクスチャ座標セット
	 * @return 二次元テクスチャ座標配列
	 */
	virtual const TexCoord2* getTexCoord2Array(int texCoordSet) const{
		Assert((texCoordSet >= 0) && (texCoordSet < texCoordSetCount_));
		Assert(texCoordTypes_[texCoordSet] == TexCoord::type2);
		return (TexCoord2*)texCoords_[texCoordSet];
	}

	//--------------------------------------------------------------------------
	/**
	 * 三次元テクスチャ座標の設定
	 * @param index インデックス
	 * @param texCoordSet テクスチャ座標セット
	 * @param texCoord 三次元テクスチャ座標
	 */
	virtual void setTexCoord3(
		int index, int texCoordSet, const TexCoord3& texCoord){
		Assert((index >= 0) && (index < vertexCount_));
		Assert((texCoordSet >= 0) && (texCoordSet < texCoordSetCount_));
		Assert(texCoordTypes_[texCoordSet] == TexCoord::type3);
		((TexCoord3*)texCoords_[texCoordSet])[index] = texCoord;
		vertexBufferChanged_ = true;
	}

	/**
	 * 三次元テクスチャ座標の取得
	 * @param index インデックス
	 * @param texCoordSet テクスチャ座標セット
	 * @return 三次元テクスチャ座標
	 */
	virtual const TexCoord3& getTexCoord3(int index, int texCoordSet) const{
		Assert((index >= 0) && (index < vertexCount_));
		Assert((texCoordSet >= 0) && (texCoordSet < texCoordSetCount_));
		Assert(texCoordTypes_[texCoordSet] == TexCoord::type3);
		return ((TexCoord3*)texCoords_[texCoordSet])[index];
	}

	/**
	 * 三次元テクスチャ座標配列の取得
	 * @param texCoordSet テクスチャ座標セット
	 * @return 三次元テクスチャ座標配列
	 */
	virtual const TexCoord3* getTexCoord3Array(int texCoordSet) const{
		Assert((texCoordSet >= 0) && (texCoordSet < texCoordSetCount_));
		Assert(texCoordTypes_[texCoordSet] == TexCoord::type3);
		return (TexCoord3*)texCoords_[texCoordSet];
	}

	//--------------------------------------------------------------------------
	/**
	 * 四次元テクスチャ座標の設定
	 * @param index インデックス
	 * @param texCoordSet テクスチャ座標セット
	 * @param texCoord 四次元テクスチャ座標
	 */
	virtual void setTexCoord4(
		int index, int texCoordSet, const TexCoord4& texCoord){
		Assert((index >= 0) && (index < vertexCount_));
		Assert((texCoordSet >= 0) && (texCoordSet < texCoordSetCount_));
		Assert(texCoordTypes_[texCoordSet] == TexCoord::type4);
		((TexCoord4*)texCoords_[texCoordSet])[index] = texCoord;
		vertexBufferChanged_ = true;
	}

	/**
	 * 四次元テクスチャ座標の取得
	 * @param index インデックス
	 * @param texCoordSet テクスチャ座標セット
	 * @return 四次元テクスチャ座標
	 */
	virtual const TexCoord4& getTexCoord4(int index, int texCoordSet) const{
		Assert((index >= 0) && (index < vertexCount_));
		Assert((texCoordSet >= 0) && (texCoordSet < texCoordSetCount_));
		Assert(texCoordTypes_[texCoordSet] == TexCoord::type4);
		return ((TexCoord4*)texCoords_[texCoordSet])[index];
	}

	/**
	 * 四次元テクスチャ座標配列の取得
	 * @param texCoordSet テクスチャ座標セット
	 * @return 四次元テクスチャ座標配列
	 */
	virtual const TexCoord4* getTexCoord4Array(int texCoordSet) const{
		Assert((texCoordSet >= 0) && (texCoordSet < texCoordSetCount_));
		Assert(texCoordTypes_[texCoordSet] == TexCoord::type4);
		return (TexCoord4*)texCoords_[texCoordSet];
	}

	//--------------------------------------------------------------------------
	// ボーン
	//--------------------------------------------------------------------------
	/**
	 * 頂点あたりボーン数の設定
	 * @param bonesPerVertex 頂点あたりボーン数
	 */
	virtual void setBonesPerVertex(int bonesPerVertex);

	/**
	 * 頂点あたりボーン数の取得
	 * @return 頂点あたりボーン数
	 */
	virtual int getBonesPerVertex() const{ return bonesPerVertex_; }

	/**
	 * ボーンインデックスが有効かどうか
	 * @return ボーンインデックスが有効ならtrue
	 */
	virtual bool hasBoneIndex() const{ return (bonesPerVertex_ > 0); }

	/**
	 * ボーンインデックスの設定
	 * @param vertexIndex 頂点インデックス
	 * @param boneNumber ボーン番号
	 * @param boneIndex ボーンインデックス
	 */
	virtual void setBoneIndex(
		int vertexIndex, int boneNumber, u_char boneIndex){
		Assert(hasBoneIndex());
		Assert((vertexIndex >= 0) && (vertexIndex < vertexCount_));
		Assert((boneNumber >= 0) && (boneNumber < bonesPerVertex_));
		boneIndices_[vertexIndex * bonesPerVertex_ + boneNumber] =
			boneIndex;
		vertexBufferChanged_ = true;
	}

	/**
	 * ボーンインデックスの設定
	 * @param vertexIndex 頂点インデックス
	 * @param boneIndex ボーンインデックス
	 */
	virtual void setBoneIndex(int vertexIndex, u_char boneIndex){
		Assert(bonesPerVertex_ == 1);
		Assert((vertexIndex >= 0) && (vertexIndex < vertexCount_));
		boneIndices_[vertexIndex] = boneIndex;
		vertexBufferChanged_ = true;
	}

	/**
	 * ボーンインデックスの取得
	 * @param vertexIndex 頂点インデックス
	 * @param boneNumber ボーン番号
	 * @return ボーンインデックス
	 */
	virtual u_char getBoneIndex(int vertexIndex, int boneNumber) const{
		Assert(hasBoneIndex());
		Assert((vertexIndex >= 0) && (vertexIndex < vertexCount_));
		Assert((boneNumber >= 0) && (boneNumber < bonesPerVertex_));
		return boneIndices_[vertexIndex * bonesPerVertex_ + boneNumber];
	}

	/**
	 * ボーンインデックスの取得
	 * @param vertexIndex 頂点インデックス
	 * @return ボーンインデックス
	 */
	virtual u_char getBoneIndex(int vertexIndex) const{
		Assert(bonesPerVertex_ == 1);
		Assert((vertexIndex >= 0) && (vertexIndex < vertexCount_));
		return boneIndices_[vertexIndex];
	}

	/**
	 * ボーンインデックス配列の取得
	 * @return ボーンインデックス配列
	 */
	virtual const u_char* getBoneIndexArray() const{ return boneIndices_; }

	//--------------------------------------------------------------------------
	// ウェイト
	//--------------------------------------------------------------------------
	/**
	 * 頂点当たりウェイト数の取得
	 * @return 頂点あたりウェイト数
	 */
	virtual int getWeightsPerVertex() const{ return weightsPerVertex_; }

	/**
	 * ウェイトが有効かどうか
	 * @return ウェイトが有効ならtrue
	 */
	virtual bool hasWeight() const{ return (weightsPerVertex_ > 0); }

	/**
	 * ウェイトの設定
	 * @param vertexIndex 頂点インデックス
	 * @param boneNumber ボーン番号
	 * @param weight ウェイト
	 */
	virtual void setWeight(int vertexIndex, int boneNumber, float weight){
		Assert(hasWeight());
		Assert((vertexIndex >= 0) && (vertexIndex < vertexCount_));
		Assert((boneNumber >= 0) && (boneNumber < bonesPerVertex_));
		weights_[vertexIndex * weightsPerVertex_ + boneNumber] = weight;
		vertexBufferChanged_ = true;
	}

	/**
	 * ウェイトの取得
	 * @param vertexIndex 頂点インデックス
	 * @param boneNumber ボーン番号
	 * @return ウェイト
	 */
	virtual float getWeight(int vertexIndex, int boneNumber) const{
		Assert(hasWeight());
		Assert((vertexIndex >= 0) && (vertexIndex < vertexCount_));
		Assert((boneNumber >= 0) && (boneNumber < bonesPerVertex_));
		return weights_[vertexIndex * weightsPerVertex_ + boneNumber];
	}

	/**
	 * ウェイト配列の取得
	 * @return ウェイト配列
	 */
	virtual const float* getWeightArray() const{ return weights_; }

	//--------------------------------------------------------------------------
	// デバイスオブジェクト
	//--------------------------------------------------------------------------
	/**
	 * デバイスオブジェクトの初期化
	 * @return 成功したらtrueを返す
	 */
	virtual bool initializeGraphicsDeviceObjects(){ return true; }

	/**
	 * デバイスオブジェクトの削除
	 */
	virtual void deleteGraphicsDeviceObjects(){}

	/**
	 * デバイスオブジェクトのリストア
	 * @return 成功したらtrueを返す
	 */
	virtual bool restoreGraphicsDeviceObjects(){ return true; }

	/**
	 * デバイスオブジェクトの無効化
	 */
	virtual void invalidateGraphicsDeviceObjects(){
		SafeRelease(indexBuffer_);
		SafeRelease(vertexBuffer_);
		vertexSize_ = 0;
		SafeRelease(vertexDeclaration_);
	}

	//--------------------------------------------------------------------------
	// RTTI
	//--------------------------------------------------------------------------
	/**
	 * メッシュデータかどうか
	 * @return メッシュデータならtrue
	 */
	virtual bool isMeshData() const{ return true; }

protected:
	//--------------------------------------------------------------------------
	/**
	 * コンストラクタ
	 * @param name 名前
	 * @param scene シーン
	 */
	MeshData(const String& name, Scene* scene);

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

	/**
	 * メッシュデータの値コピー
	 * @param destination コピー先メッシュデータ
	 */
	virtual void copyMeshDataValue(MeshData* destination) const;

	//--------------------------------------------------------------------------
	// グラフィックスバッファ
	//--------------------------------------------------------------------------
	/**
	 * インデックスバッファの取得
	 * @return インデックスバッファ
	 */
	virtual Direct3DIndexBuffer* getIndexBuffer();

	/**
	 * 頂点記述の取得
	 * @return 頂点記述
	 */
	virtual Direct3DVertexDeclaration* getVertexDeclaration();

	/**
	 * 頂点サイズの取得
	 * @return 頂点サイズ
	 */
	virtual int getVertexSize();

	/**
	 * 頂点バッファの構築
	 * @return 頂点バッファ
	 */
	virtual Direct3DVertexBuffer* getVertexBuffer();

	//--------------------------------------------------------------------------
	/**
	 * 参照の追加
	 * @param parent 親
	 * @return 参照カウント
	 */
	virtual int addReference(Mesh* parent){
		parents_.add(parent);
		return getParentCount();
	}

	/**
	 * 参照の削除
	 * @param parent 親
	 * @return 参照カウント
	 */
	virtual int removeReference(Mesh* parent){
		parents_.removeByValue(parent);
		return getParentCount();
	}

	//--------------------------------------------------------------------------
private:
	// 親配列
	ArrayList<Mesh*> parents_;
	// バウンディングスフィア
	Sphere boundingSphere_;
	// バウンディングボックス
	AxisAlignedBox boundingBox_;

	// インデックスバッファ
	Direct3DIndexBuffer* indexBuffer_;
	// 頂点記述
	Direct3DVertexDeclaration* vertexDeclaration_;
	// 頂点サイズ
	int vertexSize_;
	// 頂点バッファ
	Direct3DVertexBuffer* vertexBuffer_;

	// プリミティブタイプ
	Mesh::PrimitiveType primitiveType_;
	// 頂点インデックス数
	int vertexIndexCount_;
	// 頂点インデックス配列
	u_short* vertexIndexArray_;
	// 頂点数
	int vertexCount_;
	// 位置
	Vector3* positions_;
	// 法線
	Vector3* normals_;
	// 色
	Color4c* colors_;
	// テクスチャ座標セット数
	int texCoordSetCount_;
	// テクスチャ座標タイプ
	TexCoord::Type texCoordTypes_[TexCoord::maxSetCount];
	// テクスチャ座標
	float* texCoords_[TexCoord::maxSetCount];
	// 頂点あたりボーン数
	int bonesPerVertex_;
	// ボーンインデックス
	u_char* boneIndices_;
	// 頂点あたりウェイト数
	int weightsPerVertex_;
	// ウェイト
	float* weights_;
	// 法線フラグ
	bool normalFlag_;
	// 色フラグ
	bool colorFlag_;
	// UVフラグ
	bool uvFlag_;

	// 頂点バッファ変更フラグ
	bool vertexBufferChanged_;
	// インデックスバッファ変更フラグ
	bool indexBufferChanged_;
	// バウンディング変更フラグ
	bool boundingChanged_;

};

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