////////////////////////////////////////////////////////
// filename: ChaResourceObject.cpp
// author: Chafumi Touji
// version: 1.0.0
// date: 2020/03/08
////////////////////////////////////////////////////////

#include "defcha3dcore.h"

CMaterialResource::CMaterialResource(){

	memset(&diffuse, 0, sizeof(float)* 4);
	memset(&ambient, 0, sizeof(float)* 4);
	memset(&specular, 0, sizeof(float)* 4);
	memset(&emmition, 0, sizeof(float)* 4);
	Texture = NULL;
	ShaderResourceNum = -1;
}

CMaterialResource::~CMaterialResource(){

	memset(&diffuse, 0, sizeof(float)* 4);
	memset(&ambient, 0, sizeof(float)* 4);
	memset(&specular, 0, sizeof(float)* 4);
	memset(&emmition, 0, sizeof(float)* 4);
}

CGeometryResource::CGeometryResource(){

	VertexBuffer = NULL;
	IndexBuffer = new CVector(sizeof(int64_t **));
	IndexBufferView = new CVector(sizeof(int64_t**));
	Material = new CVector(sizeof(int64_t));
	IndexCount = new CVector(sizeof(int64_t));
	BindShapeMatrix = XMMatrixIdentity();
	memset(ObjectRect, 0, sizeof(XMFLOAT4)* 8);
	CenterPos = XMFLOAT4(0, 0, 0, 0);
	Length = 0.0f;
}

CGeometryResource::~CGeometryResource(){

	SAFE_RELEASE(VertexBuffer);
	delete VertexBufferView;
	VertexBufferView = NULL;

	for (int i = 0; i <= IndexBuffer->PushPos - 1; i++){
		ID3D12Resource **index_buffer = (ID3D12Resource **)IndexBuffer->GetData(i);
		SAFE_RELEASE( *index_buffer );
	}
	for (int i = 0; i <= IndexBufferView->PushPos - 1; i++) {
		D3D12_INDEX_BUFFER_VIEW** index_buffer_view = (D3D12_INDEX_BUFFER_VIEW**)IndexBuffer->GetData(i);
		delete *index_buffer_view;
		*index_buffer_view = NULL;
	}
	for (int i = 0; i <= Material->PushPos - 1; i++){
		CMaterialResource **data = (CMaterialResource **)Material->GetData(i);
		delete *data;
		*data = NULL;
	}

	delete IndexBuffer;
	delete IndexBufferView;
	delete Material;
	delete IndexCount;

	IndexBuffer = NULL;
	IndexBufferView = NULL;
	Material = NULL;
	IndexCount = NULL;
}

bool CGeometryResource::Inside(float x, float y, float z){

	if (x < ObjectRect[0].x)
		return false;
	if (x > ObjectRect[2].x)
		return false;
	if (y < ObjectRect[0].y)
		return false;
	if (y > ObjectRect[1].y)
		return false;
	if (z < ObjectRect[4].z)
		return false;
	if (z > ObjectRect[0].z)
		return false;

	return true;
}

////////////////////////////////////////////////////////

CBoneResource::CBoneResource(){

	wmemset(ID, 0, SIZE_CHAR_MAX);
	wmemset(Name, 0, SIZE_CHAR_MAX);
	JointParam = XMMatrixIdentity();
	InvBindMatrix = XMMatrixIdentity();
	JointParamTransformed = XMMatrixIdentity();
	BoneMatrix = XMMatrixIdentity();
	ChildBone = new CVector(sizeof(int64_t));
	ParentBone = NULL;
	Type = BONE_TYPE_UNKNOWN;
	NowChangeFrameCount = 0;
	ChangeFrameCount = 0;
	ChangeNewAnimation = false;
}

CBoneResource::~CBoneResource(){

	delete ChildBone;
	ChildBone = NULL;
	ParentBone = NULL;
}

/////////////////////////////////////////////////////////

CBoneAnimationResource::CBoneAnimationResource(){

	wmemset(Target, 0, SIZE_CHAR_MAX);
	TargetBone = NULL;
	KeyTime = new CVector(sizeof(float));
	PoseMatrix = new CVector(sizeof(XMMATRIX));
}

CBoneAnimationResource::~CBoneAnimationResource(){

	delete KeyTime;
	delete PoseMatrix;
	KeyTime = NULL;
	PoseMatrix = NULL;
	TargetBone = NULL;
}

/////////////////////////////////////////////////////////

CAnimationResource::CAnimationResource(){

	wmemset(AnimationID, 0, SIZE_CHAR_MAX);
	BoneAnimation = new CVector(sizeof(int64_t));
}

CAnimationResource::~CAnimationResource(){

	for (int i = 0; i <= BoneAnimation->PushPos - 1; i++){
		CBoneAnimation *bone_anim = *(CBoneAnimation **)BoneAnimation->GetData(i);
		delete bone_anim;
		bone_anim = NULL;
	}

	delete BoneAnimation;
	BoneAnimation = NULL;
}

////////////////////////////////////////////////////////

CChaResourceObject::CChaResourceObject(){

	ResManager = NULL;
	wmemset(ModelID, 0, SIZE_CHAR_MAX);
	GeometryResource = new CVector(sizeof(int64_t));
	TextureOrigin = new CVector(sizeof(int64_t));
	ControlBone = new CVector(sizeof(int64_t));
	BoneArray = new CVector(sizeof(int64_t));
	AnimationList = new CVector(sizeof(int64_t));
	ShaderResourceOriginNum = new CVector(sizeof(int64_t));
	FrameCount = 0;
	CurrentAnimationNum = 0;
	IsAnimated = true;
	AnimationSpeed = 1.0f;
	TransformMatrix = XMMatrixIdentity();
	Scale = XMFLOAT4(1, 1, 1, 1);
	Rotation = XMFLOAT4(0, 0, 0, 1);
	Position = XMFLOAT4(0, 0, 0, 1);
	Refrain = true;
	RefrainSec = 0.0f;
	AnimationFinished = false;
	Alpha = 1.0f;
	DataType = DATA_TYPE_ORIGINAL;
}

CChaResourceObject::~CChaResourceObject(){

	if (DataType == DATA_TYPE_ORIGINAL) {
		for (int i = 0; i <= GeometryResource->PushPos - 1; i++) {
			CGeometryResource* gmt_res = *(CGeometryResource**)GeometryResource->GetData(i);
			delete gmt_res;
			gmt_res = NULL;
		}
		for (int i = 0; i <= TextureOrigin->PushPos - 1; i++) {
			ID3D12Resource** texture = (ID3D12Resource**)TextureOrigin->GetData(i);
			SAFE_RELEASE(*texture);
			*texture = NULL;
		}
		for (int i = 0; i <= ShaderResourceOriginNum->PushPos - 1; i++) {
			int64_t* num = (int64_t*)ShaderResourceOriginNum->GetData(i);
			if (ResManager != NULL)
				ResManager->FreeResourceNum(*num);
		}
		for (int i = 0; i <= BoneArray->PushPos - 1; i++) {
			CBoneResource* bone = *(CBoneResource**)BoneArray->GetData(i);
			if (bone != NULL)
				delete bone;
			bone = NULL;
		}
		for (int i = 0; i <= ControlBone->PushPos - 1; i++) {
			CBoneResource* bone = *(CBoneResource**)ControlBone->GetData(i);
			if (bone != NULL)
				delete bone;
			bone = NULL;
		}
		for (int i = 0; i <= AnimationList->PushPos - 1; i++) {
			CAnimationResource* data = *(CAnimationResource**)AnimationList->GetData(i);
			delete data;
			data = NULL;
		}

		delete GeometryResource;
		delete TextureOrigin;
		delete ControlBone;
		delete BoneArray;
		delete AnimationList;
		delete ShaderResourceOriginNum;

		GeometryResource = NULL;
		TextureOrigin = NULL;
		ControlBone = NULL;
		BoneArray = NULL;
		AnimationList = NULL;
		ShaderResourceOriginNum = NULL;
	}

	m_pConstantBufferMaterial->Unmap(0, NULL);
	m_pConstantBufferJoint->Unmap(0, NULL);

	SAFE_RELEASE(m_pConstantBufferMaterial);
	SAFE_RELEASE(m_pConstantBufferJoint);

	m_pConstantBufferMaterial = NULL;
	m_pConstantBufferJoint = NULL;

	if (ResManager != NULL) {
		ResManager->FreeResourceNum(constant_buffer_joint_num);
		ResManager->FreeResourceNum(constant_buffer_material_num);
	}
}

int CChaResourceObject::LoadTexture( ID3D12Device *device, ID3D12Resource **pTexture, CResManager *ResManager, int64_t *ResNum, wchar_t* filename ){

	Gdiplus::Image *img = new Gdiplus::Image(filename );

	BITMAPINFO  bmi = { 0 };
	bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bmi.bmiHeader.biWidth = img->GetWidth();
	bmi.bmiHeader.biHeight = img->GetHeight();
	bmi.bmiHeader.biPlanes = 1;
	bmi.bmiHeader.biBitCount = 32;

	byte* AlphaBMP = NULL;
	HBITMAP MemBMP = CreateDIBSection(0, &bmi, DIB_RGB_COLORS, (void**)&AlphaBMP, 0, 0);

	HDC hdc = ::GetDC(NULL);
	HDC MemDC = CreateCompatibleDC(hdc);
	::SelectObject(MemDC, MemBMP);
	DeleteDC(hdc);

	Gdiplus::Graphics* gfc = new Gdiplus::Graphics(MemDC);
	gfc->DrawImage(img, 0, 0, img->GetWidth(), img->GetHeight());
	delete gfc;

	D3D12_RESOURCE_DESC descResourceTex;
	D3D12_HEAP_PROPERTIES heapProps;
	ZeroMemory(&heapProps, sizeof(heapProps));
	ZeroMemory(&descResourceTex, sizeof(descResourceTex));

	heapProps.Type = D3D12_HEAP_TYPE_CUSTOM;
	heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_WRITE_BACK;
	heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_L0;
	heapProps.CreationNodeMask = 1;
	heapProps.VisibleNodeMask = 1;

	descResourceTex.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
	descResourceTex.Width = img->GetWidth();
	descResourceTex.Height = img->GetHeight();
	descResourceTex.DepthOrArraySize = 1;
	descResourceTex.MipLevels = 1;
	descResourceTex.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
	descResourceTex.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
	descResourceTex.SampleDesc.Quality = 0;
	descResourceTex.SampleDesc.Count = 1;

	HRESULT hr = device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &descResourceTex, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(pTexture));
	if (FAILED(hr))
		return hr;

	UINT size = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
	D3D12_SHADER_RESOURCE_VIEW_DESC descSRV;
	ZeroMemory(&descSRV, sizeof(descSRV));

	descSRV.Format = DXGI_FORMAT_B8G8R8A8_UNORM;;
	descSRV.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
	descSRV.Texture2D.MipLevels = 1;
	descSRV.Texture2D.MostDetailedMip = 0;
	descSRV.Texture2D.PlaneSlice = 0;
	descSRV.Texture2D.ResourceMinLODClamp = 0.0F;
	descSRV.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;

	D3D12_CPU_DESCRIPTOR_HANDLE handle = ResManager->CreateCPUHandle(ResNum);
	device->CreateShaderResourceView(*pTexture, &descSRV, handle);

	hr = ((ID3D12Resource*)*pTexture)->WriteToSubresource(0, nullptr, &AlphaBMP[0], (UINT)(4 * img->GetWidth()), (UINT)(4 * img->GetWidth() * img->GetHeight()));

	delete img;
	DeleteDC(MemDC);
	DeleteObject(MemBMP);

	return hr;
}

bool CChaResourceObject::CreateResource(ID3D12Device *device, CChaDataObject *object, CResManager *res_manager, bool is_animated){

	if (object == NULL)
		return false;

	ResManager = res_manager;
	IsAnimated = is_animated;

	//////////////////////////////////////////////////////////////////
	// テクスチャリソース作成

	UINT heap_size = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);

	wchar_t name[SIZE_CHAR_MAX];
	for (int i = 0; i <= object->TextureName->PushPos - 1; i++){
		CTextureName* tex_name = *(CTextureName**)object->TextureName->GetData(i);
		if (tex_name != NULL && tex_name->TextureName != NULL) {
			ID3D12Resource *texture = NULL;
			wcscpy_s(name, SIZE_CHAR_MAX, tex_name->TextureName);
			int64_t res_num = 0;
			HRESULT hr = LoadTexture(device, (ID3D12Resource**) &texture, ResManager, &res_num, name);
			if ( hr == S_OK ) {
				TextureOrigin->Push((void*)&texture);
				ShaderResourceOriginNum->Push((void*)&res_num);
			}
		}
	}

	//////////////////////////////////////////////////////////////////
	//コンスタントバッファ作成

	// 定数バッファを生成.
	// ヒーププロパティの設定.
	D3D12_HEAP_PROPERTIES prop;
	ZeroMemory(&prop, sizeof(prop));
	prop.Type = D3D12_HEAP_TYPE_UPLOAD;
	prop.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
	prop.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
	prop.CreationNodeMask = 1;
	prop.VisibleNodeMask = 1;

	// リソースの設定.
	D3D12_RESOURCE_DESC desc2;
	ZeroMemory(&desc2, sizeof(desc2));
	desc2.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
	desc2.Alignment = 0;
	desc2.Width = 0x100;
	desc2.Height = 1;
	desc2.DepthOrArraySize = 1;
	desc2.MipLevels = 1;
	desc2.Format = DXGI_FORMAT_UNKNOWN;
	desc2.SampleDesc.Count = 1;
	desc2.SampleDesc.Quality = 0;
	desc2.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
	desc2.Flags = D3D12_RESOURCE_FLAG_NONE;

	// リソースを生成.
	HRESULT hr = device->CreateCommittedResource(&prop, D3D12_HEAP_FLAG_NONE, &desc2, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_ID3D12Resource, (void**)&m_pConstantBufferMaterial);

	// 定数バッファビューの設定.
	D3D12_CONSTANT_BUFFER_VIEW_DESC bufferDesc = {};
	bufferDesc.BufferLocation = m_pConstantBufferMaterial->GetGPUVirtualAddress();
	bufferDesc.SizeInBytes = 0x100;

	// 定数バッファビューを生成.
	int64_t res_num = 0;
	D3D12_CPU_DESCRIPTOR_HANDLE handle = ResManager->CreateCPUHandle(&res_num);
	device->CreateConstantBufferView(&bufferDesc, handle);
	constant_buffer_material_num = (UINT) res_num;

	// マップする. アプリケーション終了まで Unmap しない.
	hr = m_pConstantBufferMaterial->Map(0, NULL, (void**)&constant_buffer_material_begin);

	//////////////////////////////////////////////////////////////////
	//コンスタントバッファ作成

	// リソースの設定.
	ZeroMemory(&desc2, sizeof(desc2));
	desc2.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
	desc2.Alignment = 0;
	desc2.Width = ((int) sizeof( ConstantBufferJoint ) % 256 + 1 ) * 256;
	desc2.Height = 1;
	desc2.DepthOrArraySize = 1;
	desc2.MipLevels = 1;
	desc2.Format = DXGI_FORMAT_UNKNOWN;
	desc2.SampleDesc.Count = 1;
	desc2.SampleDesc.Quality = 0;
	desc2.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
	desc2.Flags = D3D12_RESOURCE_FLAG_NONE;

	// リソースを生成.
	hr = device->CreateCommittedResource(&prop, D3D12_HEAP_FLAG_NONE, &desc2, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_ID3D12Resource, (void**)&m_pConstantBufferJoint);

	// 定数バッファビューの設定.
	bufferDesc.BufferLocation = m_pConstantBufferJoint->GetGPUVirtualAddress();
	bufferDesc.SizeInBytes = ((int)sizeof(ConstantBufferJoint) % 256 + 1) * 256;

	// 定数バッファビューを生成.
	handle = ResManager->CreateCPUHandle(&res_num);
	device->CreateConstantBufferView(&bufferDesc, handle);
	constant_buffer_joint_num = (UINT) res_num;

	// マップする. アプリケーション終了まで Unmap しない.
	hr = m_pConstantBufferJoint->Map(0, NULL, (void**)&constant_buffer_joint_begin);

	//////////////////////////////////////////////////////////////////
	// バッファ作成

	wcscpy_s(ModelID, SIZE_CHAR_MAX, object->ModelID);

	for (int i = 0; i <= object->Geometry->PushPos - 1; i++){

		CGeometry *gmt = *(CGeometry **)object->Geometry->GetData(i);
		CGeometryResource *gmt_res = new CGeometryResource();
		XMMATRIX bind_matrix = XMMATRIX(gmt->BindShapeMatrix.m11, gmt->BindShapeMatrix.m12, gmt->BindShapeMatrix.m13, gmt->BindShapeMatrix.m14,
			gmt->BindShapeMatrix.m21, gmt->BindShapeMatrix.m22, gmt->BindShapeMatrix.m23, gmt->BindShapeMatrix.m24,
			gmt->BindShapeMatrix.m31, gmt->BindShapeMatrix.m32, gmt->BindShapeMatrix.m33, gmt->BindShapeMatrix.m34,
			gmt->BindShapeMatrix.m41, gmt->BindShapeMatrix.m42, gmt->BindShapeMatrix.m43, gmt->BindShapeMatrix.m44);
		gmt_res->BindShapeMatrix = XMMatrixTranspose(bind_matrix);

		int vertex_count = gmt->VertexCount;
		char *buffer = new char[sizeof(CVertex)* (vertex_count)];
		memset(buffer, 0, sizeof(CVertex)* (vertex_count));
		char *data = new char[sizeof(CVertex)];
		int vertex_pos = 0;

		for (int j = 0; j <= gmt->PolygonData->PushPos - 1; j++){

			CPolygonData *pgn_data = *(CPolygonData **)gmt->PolygonData->GetData(j);

			int64_t tex_num = pgn_data->TexID->PushPos;

			int64_t** tex_data = NULL;
			if (tex_num >= 1) {
				tex_data = (int64_t**) new int64_t[tex_num];
				for (int k = 0; k <= tex_num - 1; k++)
					tex_data[k] = (int64_t*)gmt->GetFloatArray((wchar_t*)pgn_data->TexID->GetData(k));
			}

			CFloatArray *vertex_data = gmt->GetFloatArray(pgn_data->VertexID);
			CFloatArray *normal_data = gmt->GetFloatArray(pgn_data->NormalID);
			CFloatArray *color_data = gmt->GetFloatArray(pgn_data->ColorID);

			//Material取得
			CMaterial *material = object->GetMaterial(pgn_data->MaterialID);
			ID3D12Resource *texture = NULL;
			CMaterialResource *material_resource = new CMaterialResource();
			if (material != NULL){
				int material_num = object->GetMaterialNum(pgn_data->MaterialID);
				int texture_num = object->GetTextureNum(material_num);
				int64_t *res_num = NULL;
				if (texture_num >= 0){
					texture = (ID3D12Resource *)TextureOrigin->GetData(texture_num);
					res_num = (int64_t *) ShaderResourceOriginNum->GetData(texture_num);
					material_resource->Texture = texture;
					material_resource->ShaderResourceNum = (UINT) *res_num;
				}
				material_resource->diffuse = material->diffuse;
				material_resource->ambient = material->ambient;
				material_resource->emmition = material->emmition;
				material_resource->specular = material->specular;
			}
			gmt_res->Material->Push((void *)&material_resource);

			int64_t index_count = pgn_data->VertexIndex->PushPos;
			int *buffer_index = new int32_t[index_count];
			memset(buffer_index, 0, (index_count)* sizeof(int32_t));

			float3 vertex;
			float3 normal;
			float4 color;
			float2 tex;
			float2 weight[WEIGHT_BONE_APPLY_NUM];
			memset(weight, 0, sizeof(float2)* WEIGHT_BONE_APPLY_NUM);

			for (int k = 0; k <= pgn_data->VertexIndex->PushPos - 1; k++){
				memset(data, 0, sizeof(CVertex));
				memset(&vertex, 0, sizeof(float3));
				memset(&normal, 0, sizeof(float3));
				memset(&color, 0, sizeof(float4));
				memset(&tex, 0, sizeof(float2));
				memset(weight, 0, sizeof(float2)* WEIGHT_BONE_APPLY_NUM);
				if (vertex_data != NULL){
					int vertex_index = *(int *)pgn_data->VertexIndex->GetData(k);
					vertex = *(float3 *)vertex_data->FloatData->GetData(vertex_index);
					vertex_pos = vertex_index;
					if (gmt->Weights != NULL){
						int64_t **weights = gmt->Weights[vertex_index];
						for (int l = 0; l <= WEIGHT_BONE_APPLY_NUM - 1; l++){
							float2 *w = (float2 *)weights[l];
							weight[l].x = w->x;
							weight[l].y = w->y;
						}
					}

					//オブジェクトのポリゴンを包む長方形の大きさを計算
					if (vertex.x < gmt_res->ObjectRect[0].x)
						gmt_res->ObjectRect[0].x = vertex.x;
					if (vertex.x < gmt_res->ObjectRect[1].x)
						gmt_res->ObjectRect[1].x = vertex.x;
					if (vertex.x < gmt_res->ObjectRect[4].x)
						gmt_res->ObjectRect[4].x = vertex.x;
					if (vertex.x < gmt_res->ObjectRect[5].x)
						gmt_res->ObjectRect[5].x = vertex.x;
					if (vertex.x > gmt_res->ObjectRect[2].x)
						gmt_res->ObjectRect[2].x = vertex.x;
					if (vertex.x > gmt_res->ObjectRect[3].x)
						gmt_res->ObjectRect[3].x = vertex.x;
					if (vertex.x > gmt_res->ObjectRect[6].x)
						gmt_res->ObjectRect[6].x = vertex.x;
					if (vertex.x > gmt_res->ObjectRect[7].x)
						gmt_res->ObjectRect[7].x = vertex.x;

					if (vertex.y < gmt_res->ObjectRect[0].y)
						gmt_res->ObjectRect[0].y = vertex.y;
					if (vertex.y < gmt_res->ObjectRect[3].y)
						gmt_res->ObjectRect[3].y = vertex.y;
					if (vertex.y < gmt_res->ObjectRect[4].y)
						gmt_res->ObjectRect[4].y = vertex.y;
					if (vertex.y < gmt_res->ObjectRect[7].y)
						gmt_res->ObjectRect[7].y = vertex.y;
					if (vertex.y > gmt_res->ObjectRect[1].y)
						gmt_res->ObjectRect[1].y = vertex.y;
					if (vertex.y > gmt_res->ObjectRect[2].y)
						gmt_res->ObjectRect[2].y = vertex.y;
					if (vertex.y > gmt_res->ObjectRect[5].y)
						gmt_res->ObjectRect[5].y = vertex.y;
					if (vertex.y > gmt_res->ObjectRect[6].y)
						gmt_res->ObjectRect[6].y = vertex.y;

					if (vertex.z < gmt_res->ObjectRect[4].z)
						gmt_res->ObjectRect[4].z = vertex.z;
					if (vertex.z < gmt_res->ObjectRect[5].z)
						gmt_res->ObjectRect[5].z = vertex.z;
					if (vertex.z < gmt_res->ObjectRect[6].z)
						gmt_res->ObjectRect[6].z = vertex.z;
					if (vertex.z < gmt_res->ObjectRect[7].z)
						gmt_res->ObjectRect[7].z = vertex.z;
					if (vertex.z > gmt_res->ObjectRect[0].z)
						gmt_res->ObjectRect[0].z = vertex.z;
					if (vertex.z > gmt_res->ObjectRect[1].z)
						gmt_res->ObjectRect[1].z = vertex.z;
					if (vertex.z > gmt_res->ObjectRect[2].z)
						gmt_res->ObjectRect[2].z = vertex.z;
					if (vertex.z > gmt_res->ObjectRect[3].z)
						gmt_res->ObjectRect[3].z = vertex.z;

					gmt_res->CenterPos.x = (gmt_res->ObjectRect[0].x + gmt_res->ObjectRect[3].x) / 2.0f;
					gmt_res->CenterPos.y = (gmt_res->ObjectRect[0].y + gmt_res->ObjectRect[1].y) / 2.0f;
					gmt_res->CenterPos.z = (gmt_res->ObjectRect[0].z + gmt_res->ObjectRect[4].z) / 2.0f;

					gmt_res->Length = (float)sqrt(pow(gmt_res->CenterPos.x - gmt_res->ObjectRect[0].x, 2.0f) + pow(gmt_res->CenterPos.y - gmt_res->ObjectRect[0].y, 2.0f) + pow(gmt_res->CenterPos.z - gmt_res->ObjectRect[0].z, 2.0f));
				}
				if (normal_data != NULL){
					int normal_index = *(int *)pgn_data->NormalIndex->GetData(k);
					normal = *(float3 *)normal_data->FloatData->GetData(normal_index);
				}
				if (color_data != NULL){
					int color_index = *(int *)pgn_data->ColorIndex->GetData(k);
					color = *(float4 *)color_data->FloatData->GetData(color_index);
				}
				if (tex_data != NULL){
					int tex_index = *(int *)pgn_data->TexIndex->GetData(k);
					for (int l = 0; l <= tex_num - 1; l++){
						CFloatArray *float_array = (CFloatArray *)tex_data[l];
						float2 tex_tmp = *(float2 *)float_array->FloatData->GetData(tex_index);
						tex.x += tex_tmp.x;
						tex.y += tex_tmp.y;
					}
				}
				memcpy_s((char *)data, sizeof(float3), &vertex, sizeof(float3));
				memcpy_s((char *)data + sizeof(float3), sizeof(float3), &normal, sizeof(float3));
				memcpy_s((char *)data + sizeof(float3)+sizeof(float3), sizeof(float4), &color, sizeof(float4));
				memcpy_s((char *)data + sizeof(float3)+sizeof(float3)+sizeof(float4), sizeof(float2), &tex, sizeof(float2));
				memcpy_s((char *)data + sizeof(float3)+sizeof(float3)+sizeof(float4)+sizeof(float2), sizeof(float2)* WEIGHT_BONE_APPLY_NUM, weight, sizeof(float2)* WEIGHT_BONE_APPLY_NUM);
				memcpy_s((char *)buffer + vertex_pos * sizeof(CVertex), sizeof(CVertex), data, sizeof(CVertex));
				buffer_index[k] = *(int *)pgn_data->VertexIndex->GetData(k);
			}

			//オブジェクトのセンター位置計算
			gmt_res->CenterPos.x = (gmt_res->ObjectRect[0].x + gmt_res->ObjectRect[3].x) / 2.0f;
			gmt_res->CenterPos.y = (gmt_res->ObjectRect[0].y + gmt_res->ObjectRect[1].y) / 2.0f;
			gmt_res->CenterPos.z = (gmt_res->ObjectRect[0].z + gmt_res->ObjectRect[4].z) / 2.0f;
			gmt_res->Length = (float)sqrt(pow(gmt_res->CenterPos.x - gmt_res->ObjectRect[0].x, 2.0f) + pow(gmt_res->CenterPos.y - gmt_res->ObjectRect[0].y, 2.0f) + pow(gmt_res->CenterPos.z - gmt_res->ObjectRect[0].z, 2.0f));

			// ヒーププロパティの設定.
			ZeroMemory(&prop, sizeof(prop));
			prop.Type = D3D12_HEAP_TYPE_UPLOAD;
			prop.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
			prop.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
			prop.CreationNodeMask = 1;
			prop.VisibleNodeMask = 1;

			// リソースの設定.
			D3D12_RESOURCE_DESC desc_index;
			ZeroMemory(&desc_index, sizeof(desc_index));
			desc_index.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
			desc_index.Alignment = 0;
			desc_index.Width = sizeof(int) * index_count;
			desc_index.Height = 1;
			desc_index.DepthOrArraySize = 1;
			desc_index.MipLevels = 1;
			desc_index.Format = DXGI_FORMAT_UNKNOWN;
			desc_index.SampleDesc.Count = 1;
			desc_index.SampleDesc.Quality = 0;
			desc_index.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
			desc_index.Flags = D3D12_RESOURCE_FLAG_NONE;

			// リソースを生成.
			ID3D12Resource* index_buffer;
			hr = device->CreateCommittedResource(&prop, D3D12_HEAP_FLAG_NONE, &desc_index, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&index_buffer));

			UINT8* pData;
			hr = index_buffer->Map(0, NULL, (void**)(&pData));
			memcpy(pData, &buffer_index[0], sizeof(int)* index_count);
			index_buffer->Unmap(0, NULL);

			D3D12_INDEX_BUFFER_VIEW *index_buffer_view = new D3D12_INDEX_BUFFER_VIEW;
			index_buffer_view->BufferLocation = index_buffer->GetGPUVirtualAddress();
			index_buffer_view->Format = DXGI_FORMAT_R32_UINT;
			index_buffer_view->SizeInBytes = (UINT) ( sizeof(int32_t) * index_count);

			gmt_res->IndexBuffer->Push((void*)&index_buffer);
			gmt_res->IndexBufferView->Push((void *)&index_buffer_view);
			gmt_res->IndexCount->Push((void *)&index_count);

			delete[] buffer_index;
			if( tex_data != NULL )
				delete[] tex_data;
		}

		// ヒーププロパティの設定.
		ZeroMemory(&prop, sizeof(prop));
		prop.Type = D3D12_HEAP_TYPE_UPLOAD;
		prop.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
		prop.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
		prop.CreationNodeMask = 1;
		prop.VisibleNodeMask = 1;

		// リソースの設定.
		D3D12_RESOURCE_DESC desc_buffer;
		ZeroMemory(&desc_buffer, sizeof(desc_buffer));
		desc_buffer.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
		desc_buffer.Alignment = 0;
		desc_buffer.Width = sizeof(CVertex) * vertex_count;
		desc_buffer.Height = 1;
		desc_buffer.DepthOrArraySize = 1;
		desc_buffer.MipLevels = 1;
		desc_buffer.Format = DXGI_FORMAT_UNKNOWN;
		desc_buffer.SampleDesc.Count = 1;
		desc_buffer.SampleDesc.Quality = 0;
		desc_buffer.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
		desc_buffer.Flags = D3D12_RESOURCE_FLAG_NONE;

		// リソースを生成.
		ID3D12Resource* vertex_buffer;
		hr = device->CreateCommittedResource(&prop, D3D12_HEAP_FLAG_NONE, &desc_buffer, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&vertex_buffer));

		UINT8* pData;
		hr = vertex_buffer->Map(0, NULL, (void**)(&pData));
		memcpy(pData, &buffer[0], sizeof(CVertex) * vertex_count);
		vertex_buffer->Unmap(0, NULL);

		// 頂点バッファビューの設定.
		gmt_res->VertexBufferView = new D3D12_VERTEX_BUFFER_VIEW;
		gmt_res->VertexBufferView->BufferLocation = vertex_buffer->GetGPUVirtualAddress();
		gmt_res->VertexBufferView->StrideInBytes = sizeof(CVertex);
		gmt_res->VertexBufferView->SizeInBytes = sizeof(CVertex) * vertex_count;

		gmt_res->VertexBuffer = vertex_buffer;
		GeometryResource->Push((void *)&gmt_res);

		delete[] data;
		delete[] buffer;
	}

	//コントロールボーンのコピー
	CopyControlBone(object);

	//アニメーションのコピー
	CopyAnimation(object);

	return true;
}

bool CChaResourceObject::CopyControlBone(CChaDataObject *object){

	for (int i = 0; i <= object->BoneArray->PushPos - 1; i++){

		CBone *bone = *(CBone **)object->BoneArray->GetData(i);
		CBoneResource *bone_res = new CBoneResource();
		bone_res->BoneMatrix = XMMatrixIdentity();
		wcscpy_s(bone_res->ID, SIZE_CHAR_MAX, bone->ID);
		wcscpy_s(bone_res->Name, SIZE_CHAR_MAX, bone->Name);
		XMMATRIX inv_matrix = XMMATRIX(bone->InvBindMatrix.m11, bone->InvBindMatrix.m12, bone->InvBindMatrix.m13, bone->InvBindMatrix.m14, bone->InvBindMatrix.m21, bone->InvBindMatrix.m22, bone->InvBindMatrix.m23, bone->InvBindMatrix.m24, bone->InvBindMatrix.m31, bone->InvBindMatrix.m32, bone->InvBindMatrix.m33, bone->InvBindMatrix.m34, bone->InvBindMatrix.m41, bone->InvBindMatrix.m42, bone->InvBindMatrix.m43, bone->InvBindMatrix.m44);
		bone_res->InvBindMatrix = XMMatrixTranspose(inv_matrix);
		XMMATRIX joint = XMMATRIX(bone->JointParam.m11, bone->JointParam.m12, bone->JointParam.m13, bone->JointParam.m14, bone->JointParam.m21, bone->JointParam.m22, bone->JointParam.m23, bone->JointParam.m24, bone->JointParam.m31, bone->JointParam.m32, bone->JointParam.m33, bone->JointParam.m34, bone->JointParam.m41, bone->JointParam.m42, bone->JointParam.m43, bone->JointParam.m44);
		bone_res->JointParam = XMMatrixTranspose(joint);
		bone_res->JointParamTransformed = XMMatrixIdentity();
		bone_res->ParentBone = NULL;
		bone_res->Type = bone->Type;
		BoneArray->Push((void *)&bone_res);
	}

	for (int i = 0; i <= object->ControlBone->PushPos - 1; i++){

		CBone *bone = *(CBone **)object->ControlBone->GetData(i);
		CBoneResource *bone_res = FindBoneByID(bone->ID);
		if (bone_res == NULL)
			bone_res = new CBoneResource();
		bone_res->BoneMatrix = XMMatrixIdentity();
		wcscpy_s(bone_res->ID, SIZE_CHAR_MAX, bone->ID);
		wcscpy_s(bone_res->Name, SIZE_CHAR_MAX, bone->Name);
		XMMATRIX bind = XMMatrixSet(bone->InvBindMatrix.m11, bone->InvBindMatrix.m12, bone->InvBindMatrix.m13, bone->InvBindMatrix.m14, bone->InvBindMatrix.m21, bone->InvBindMatrix.m22, bone->InvBindMatrix.m23, bone->InvBindMatrix.m24, bone->InvBindMatrix.m31, bone->InvBindMatrix.m32, bone->InvBindMatrix.m33, bone->InvBindMatrix.m34, bone->InvBindMatrix.m41, bone->InvBindMatrix.m42, bone->InvBindMatrix.m43, bone->InvBindMatrix.m44);
		bone_res->InvBindMatrix = XMMatrixTranspose(bind);
		XMMATRIX joint = XMMatrixSet(bone->JointParam.m11, bone->JointParam.m12, bone->JointParam.m13, bone->JointParam.m14, bone->JointParam.m21, bone->JointParam.m22, bone->JointParam.m23, bone->JointParam.m24, bone->JointParam.m31, bone->JointParam.m32, bone->JointParam.m33, bone->JointParam.m34, bone->JointParam.m41, bone->JointParam.m42, bone->JointParam.m43, bone->JointParam.m44);
		bone_res->JointParam = XMMatrixTranspose(joint);
		bone_res->JointParamTransformed = XMMatrixIdentity();
		bone_res->ParentBone = NULL;
		bone_res->Type = bone->Type;
		CopyChildBone(bone, bone_res);
		ControlBone->Push((void *)&bone_res);
	}

	return true;
}

bool CChaResourceObject::CopyChildBone(CBone *parent, CBoneResource *parent_res){

	if (parent == NULL || parent->ChildBone == NULL)
		return false;

	for (int i = 0; i <= parent->ChildBone->PushPos - 1; i++){
		CBone *bone = *(CBone **)parent->ChildBone->GetData(i);
		CBoneResource *bone_res = FindBoneByID(bone->ID);
		if (bone_res == NULL)
			bone_res = new CBoneResource();
		bone_res->BoneMatrix = XMMatrixIdentity();
		wcscpy_s(bone_res->ID, SIZE_CHAR_MAX, bone->ID);
		wcscpy_s(bone_res->Name, SIZE_CHAR_MAX, bone->Name);
		XMMATRIX inv_matrix = XMMATRIX(bone->InvBindMatrix.m11, bone->InvBindMatrix.m12, bone->InvBindMatrix.m13, bone->InvBindMatrix.m14,
			bone->InvBindMatrix.m21, bone->InvBindMatrix.m22, bone->InvBindMatrix.m23, bone->InvBindMatrix.m24,
			bone->InvBindMatrix.m31, bone->InvBindMatrix.m32, bone->InvBindMatrix.m33, bone->InvBindMatrix.m34,
			bone->InvBindMatrix.m41, bone->InvBindMatrix.m42, bone->InvBindMatrix.m43, bone->InvBindMatrix.m44);
		bone_res->InvBindMatrix = XMMatrixTranspose(inv_matrix);
		XMMATRIX joint = XMMATRIX(bone->JointParam.m11, bone->JointParam.m12, bone->JointParam.m13, bone->JointParam.m14,
			bone->JointParam.m21, bone->JointParam.m22, bone->JointParam.m23, bone->JointParam.m24,
			bone->JointParam.m31, bone->JointParam.m32, bone->JointParam.m33, bone->JointParam.m34,
			bone->JointParam.m41, bone->JointParam.m42, bone->JointParam.m43, bone->JointParam.m44);
		bone_res->JointParam = XMMatrixTranspose(joint);
		bone_res->JointParamTransformed = XMMatrixIdentity();
		bone_res->BoneMatrix = XMMatrixIdentity();
		bone_res->ParentBone = parent_res;
		parent_res->ChildBone->Push((void *)&bone_res);
		CopyChildBone(bone, bone_res);
	}

	return true;
}

bool CChaResourceObject::CopyAnimation(CChaDataObject *object){

	for (int i = 0; i <= object->AnimationList->PushPos - 1; i++){
		CAnimation *anim = *(CAnimation **)object->AnimationList->GetData(i);
		CAnimationResource *anim_res = new CAnimationResource();
		wcscpy_s(anim_res->AnimationID, SIZE_CHAR_MAX, anim->AnimatonID);
		for (int j = 0; j <= anim->BoneAnimation->PushPos - 1; j++){
			CBoneAnimation *bone_anim = *(CBoneAnimation **)anim->BoneAnimation->GetData(j);
			CBoneAnimationResource *bone_anim_res = new CBoneAnimationResource();
			wcscpy_s(bone_anim_res->Target, SIZE_CHAR_MAX, bone_anim->Target);
			bone_anim_res->TargetBone = FindBoneByID(bone_anim->Target);
			for (int k = 0; k <= bone_anim->KeyTime->PushPos - 1; k++){
				bone_anim_res->KeyTime->Push((float*)bone_anim->KeyTime->GetData(k));
			}
			for (int k = 0; k <= bone_anim->PoseMatrix->PushPos - 1; k++){
				matrix *mtx = (matrix *)bone_anim->PoseMatrix->GetData(k);
				XMMATRIX pose = XMMATRIX(mtx->m11, mtx->m12, mtx->m13, mtx->m14, mtx->m21, mtx->m22, mtx->m23, mtx->m24, mtx->m31, mtx->m32, mtx->m33, mtx->m34, mtx->m41, mtx->m42, mtx->m43, mtx->m44);
				XMMATRIX pose_matrix = XMMatrixTranspose(pose);
				bone_anim_res->PoseMatrix->Push((void *)&pose_matrix);
			}
			anim_res->BoneAnimation->Push((void *)&bone_anim_res);
		}
		AnimationList->Push((void *)&anim_res);
	}

	return true;
}

bool CChaResourceObject::CopyAnimation(CChaDataObject *object, int anim_num){

	CAnimation *anim = *(CAnimation **)object->AnimationList->GetData(anim_num);
	if (anim == NULL)
		return false;

	CAnimationResource *anim_res = new CAnimationResource();
	wcscpy_s(anim_res->AnimationID, SIZE_CHAR_MAX, anim->AnimatonID);
	for (int j = 0; j <= anim->BoneAnimation->PushPos - 1; j++){
		CBoneAnimation *bone_anim = *(CBoneAnimation **)anim->BoneAnimation->GetData(j);
		CBoneAnimationResource *bone_anim_res = new CBoneAnimationResource();
		wcscpy_s(bone_anim_res->Target, SIZE_CHAR_MAX, bone_anim->Target);
		bone_anim_res->TargetBone = FindBoneByID(bone_anim->Target);
		for (int k = 0; k <= bone_anim->KeyTime->PushPos - 1; k++){
			bone_anim_res->KeyTime->Push((float*)bone_anim->KeyTime->GetData(k));
		}
		for (int k = 0; k <= bone_anim->PoseMatrix->PushPos - 1; k++){
			matrix *mtx = (matrix *)bone_anim->PoseMatrix->GetData(k);
			XMMATRIX pose = XMMATRIX(mtx->m11, mtx->m12, mtx->m13, mtx->m14, mtx->m21, mtx->m22, mtx->m23, mtx->m24, mtx->m31, mtx->m32, mtx->m33, mtx->m34, mtx->m41, mtx->m42, mtx->m43, mtx->m44);
			XMMATRIX pose_matrix = XMMatrixTranspose(pose);
			bone_anim_res->PoseMatrix->Push((void *)&pose_matrix);
		}
		anim_res->BoneAnimation->Push((void *)&bone_anim_res);
	}
	AnimationList->Push((void *)&anim_res);

	return true;
}

CBoneResource *CChaResourceObject::FindBoneByID(wchar_t *search_name){

	if (search_name == NULL)
		return NULL;

	for (int i = 0; i <= (int)BoneArray->PushPos - 1; i++){
		CBoneResource *bone = *(CBoneResource **)BoneArray->GetData(i);
		if (wcscmp(bone->ID, search_name) == 0)
			return bone;
	}

	return NULL;
}

///////////////////////////////////////////////////////////////////////////////

bool CChaResourceObject::SetRefrainSec(float sec) {

	RefrainSec = sec;

	return true;
}

bool CChaResourceObject::SetScale(float scale_x, float scale_y, float scale_z, float scale_r ){

	Scale.x = scale_x;
	Scale.y = scale_y;
	Scale.z = scale_z;
	Scale.w = scale_r;

	return true;
}

bool CChaResourceObject::SetRotation(float angle_x, float angle_y, float angle_z){

	Rotation.x = angle_x;
	Rotation.y = angle_y;
	Rotation.z = angle_z;

	return true;
}

bool CChaResourceObject::SetPosition(float pos_x, float pos_y, float pos_z){

	Position.x = pos_x;
	Position.y = pos_y;
	Position.z = pos_z;

	return true;
}

bool CChaResourceObject::SetToneLightPos(float pos_x, float pos_y, float pos_z){

	ToneLightPosition.x = pos_x;
	ToneLightPosition.y = pos_y;
	ToneLightPosition.z = pos_z;

	return true;
}

bool CChaResourceObject::SetAlpha(float alpha){

	Alpha = alpha;

	if (Alpha > 1.0f)
		Alpha = 1.0f;
	if (Alpha < 0.0f)
		Alpha = 0.0f;

	return true;
}

bool CChaResourceObject::Draw(ID3D12GraphicsCommandList *m_pCmdList, int cbf_slot_1, int cbf_slot_2, int root_signature_slot ){

	ConstantBufferMaterial		constant_buffer_material;
	ConstantBufferJoint			constant_buffer_joint;

	for (int i = 0; i <= BoneArray->PushPos - 1; i++){

		CBoneResource *bone_res = *(CBoneResource **)BoneArray->GetData(i);
		XMMATRIX mtx = bone_res->BoneMatrix;
		XMStoreFloat4x4(&constant_buffer_joint.BoneMatrix[i], XMMatrixTranspose(mtx));
	}

	XMStoreFloat4x4(&constant_buffer_joint.MatTransform, XMMatrixTranspose(TransformMatrix));
	XMStoreFloat4x4(&constant_buffer_joint.MatNormalTransform, XMMatrixTranspose(NormalTransformMatrix));
	constant_buffer_joint.ToneLightPos = ToneLightPosition;

	UINT stride = sizeof(CVertex);
	UINT offset = 0;
	// プリミティブトポロジーの設定.
	m_pCmdList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

	for (int i = 0; i <= GeometryResource->PushPos - 1; i++){

		CGeometryResource *gmt_res = *(CGeometryResource **)GeometryResource->GetData(i);

		// 頂点バッファビューを設定.
		m_pCmdList->IASetVertexBuffers(0, 1, gmt_res->VertexBufferView);
		m_pCmdList->SetGraphicsRootConstantBufferView(cbf_slot_1, m_pConstantBufferMaterial->GetGPUVirtualAddress());
		m_pCmdList->SetGraphicsRootConstantBufferView(cbf_slot_2, m_pConstantBufferJoint->GetGPUVirtualAddress());

		XMStoreFloat4x4(&constant_buffer_joint.BindShapeMatrix, XMMatrixTranspose(gmt_res->BindShapeMatrix));
		memcpy(constant_buffer_joint_begin, &constant_buffer_joint, sizeof(constant_buffer_joint));

		for (int j = 0; j <= gmt_res->IndexBufferView->PushPos - 1; j++){

			D3D12_INDEX_BUFFER_VIEW **index_buffer_view = (D3D12_INDEX_BUFFER_VIEW**)gmt_res->IndexBufferView->GetData(j);
			m_pCmdList->IASetIndexBuffer(*index_buffer_view);

			CMaterialResource *material = *(CMaterialResource **)gmt_res->Material->GetData(j);
			if (material != NULL){

				constant_buffer_material.Diffuse = XMFLOAT4(material->diffuse.x, material->diffuse.y, material->diffuse.z, material->diffuse.w);
				constant_buffer_material.Ambient = XMFLOAT4(material->ambient.x, material->ambient.y, material->ambient.z, material->ambient.w);
				constant_buffer_material.Specular = XMFLOAT4(material->specular.x, material->specular.y, material->specular.z, material->specular.w);
				constant_buffer_material.AlphaParam = XMFLOAT4(Alpha, 0, 0, 0);

				memcpy(constant_buffer_material_begin, &constant_buffer_material, sizeof(constant_buffer_material));
				
				if (material->ShaderResourceNum >= 0 ) {
					if (material->Texture != NULL) {
						D3D12_GPU_DESCRIPTOR_HANDLE handle = ResManager->GetGPUHandle(material->ShaderResourceNum);
						m_pCmdList->SetGraphicsRootDescriptorTable(root_signature_slot, handle);
					}
				}
			}

			int32_t *index_count = (int32_t *)gmt_res->IndexCount->GetData(j);
			m_pCmdList->DrawIndexedInstanced(*index_count, 1, 0, 0, 0);
		}
	}

	return true;
}

XMMATRIX CChaResourceObject::GetAnimationMatrix(CBoneAnimationResource *anim, float sec, int *finished){

	XMMATRIX matrix = XMMatrixIdentity();

	if ((int)anim->PoseMatrix->PushPos <= 0)
		return matrix;

	float end_time = *(float*)anim->KeyTime->GetData((int) anim->KeyTime->PushPos - 1);

	*finished = false;
	if (end_time < sec){
		*finished = true;
		FrameCount = 0;
		sec = end_time;
		if (Refrain == true)
			sec = RefrainSec;
		return *(XMMATRIX *)anim->PoseMatrix->GetData((int) anim->PoseMatrix->PushPos - 1);
	}

	int sec_int = (int)(sec * 10000);
	int sec_end = (int)(end_time * 10000);
	int time_int = sec_int % sec_end;
	float time = ((float)time_int) / 10000.000f;

	int matrix_num = 0;
	while (*(float *)anim->KeyTime->GetData(matrix_num) < time){
		matrix_num++;
	}
	if (matrix_num > (int)anim->KeyTime->PushPos - 1)
		return matrix;

	XMMATRIX matrix1 = XMMatrixIdentity();
	XMMATRIX matrix2 = XMMatrixIdentity();
	if (matrix_num == 0){
		return *(XMMATRIX *)anim->PoseMatrix->GetData(0);
	}
	matrix1 = *(XMMATRIX *)anim->PoseMatrix->GetData(matrix_num - 1);
	matrix2 = *(XMMATRIX *)anim->PoseMatrix->GetData(matrix_num);

	float key_time1, key_time2;
	key_time1 = *(float*)anim->KeyTime->GetData(matrix_num - 1);
	key_time2 = *(float*)anim->KeyTime->GetData(matrix_num);
	float pos = (time - key_time1) / (key_time2 - key_time1);
	XMMATRIX matrix_out = CalcInterPauseLinear(matrix1, matrix2, pos);

	return matrix_out;
}

XMMATRIX CChaResourceObject::CalcInterPauseLinear(XMMATRIX matrix1, XMMATRIX matrix2, float t){

	XMMATRIX matrix_out;
	matrix_out._11 = matrix1._11 + (matrix2._11 - matrix1._11) * t;
	matrix_out._12 = matrix1._12 + (matrix2._12 - matrix1._12) * t;
	matrix_out._13 = matrix1._13 + (matrix2._13 - matrix1._13) * t;
	matrix_out._14 = matrix1._14 + (matrix2._14 - matrix1._14) * t;
	matrix_out._21 = matrix1._21 + (matrix2._21 - matrix1._21) * t;
	matrix_out._22 = matrix1._22 + (matrix2._22 - matrix1._22) * t;
	matrix_out._23 = matrix1._23 + (matrix2._23 - matrix1._23) * t;
	matrix_out._24 = matrix1._24 + (matrix2._24 - matrix1._24) * t;
	matrix_out._31 = matrix1._31 + (matrix2._31 - matrix1._31) * t;
	matrix_out._32 = matrix1._32 + (matrix2._32 - matrix1._32) * t;
	matrix_out._33 = matrix1._33 + (matrix2._33 - matrix1._33) * t;
	matrix_out._34 = matrix1._34 + (matrix2._34 - matrix1._34) * t;
	matrix_out._41 = matrix1._41 + (matrix2._41 - matrix1._41) * t;
	matrix_out._42 = matrix1._42 + (matrix2._42 - matrix1._42) * t;
	matrix_out._43 = matrix1._43 + (matrix2._43 - matrix1._43) * t;
	matrix_out._44 = matrix1._44 + (matrix2._44 - matrix1._44) * t;

	return matrix_out;
}

////////////////////////////////////////////////////////////////////////////
// ボーンの変形

bool CChaResourceObject::BoneTransform(CBoneResource *bone){

	XMVECTOR vec;
	if (bone->ParentBone == NULL){
		bone->BoneMatrix = bone->InvBindMatrix * bone->JointParamTransformed * XMMatrixInverse(&vec, bone->InvBindMatrix * bone->JointParam);
	}
	else{
		bone->BoneMatrix = bone->InvBindMatrix * bone->JointParamTransformed * XMMatrixInverse(&vec, bone->InvBindMatrix * bone->JointParam) * bone->ParentBone->BoneMatrix;
	}
	for (int i = 0; i <= (int)bone->ChildBone->PushPos - 1; i++){
		BoneTransform(*(CBoneResource **)bone->ChildBone->GetData(i));
	}

	return true;
}

bool CChaResourceObject::SetCurrentAnimation(int num, int change_frame_count, float anim_speed, bool refrain, bool model_swapped  ){

	if (num < 0 || num >= AnimationList->PushPos)
		return false;

	////////////////////////////////////////////////////////////////////////
	//現在のアニメーションから新しいアニメーションへ補完しながら移行。

	if (model_swapped == true) {
		//モデルが入れ替わった時には補間せずに移行。
		CurrentAnimationNum = num;
		FrameCount = change_frame_count;
	}

	AnimationSpeed = anim_speed;
	AnimationFinished = false;
	Refrain = refrain;
	CAnimationResource *anim_res_prev = *(CAnimationResource **)AnimationList->GetData(CurrentAnimationNum);
	CAnimationResource *anim_res_new = *(CAnimationResource **)AnimationList->GetData(num);

	float sec = (float)FrameCount  * AnimationSpeed / 50.00f;

	for (int i = 0; i <= BoneArray->PushPos - 1; i++){
		CBoneResource *bone = *(CBoneResource **)BoneArray->GetData(i);
		bone->NowChangeFrameCount = 0;
		bone->ChangeFrameCount = 0;
		bone->ChangeNewAnimation = false;
	}

	int finished = false;
	for (int i = 0; i <= (int)anim_res_new->BoneAnimation->PushPos - 1; i++){

		CBoneAnimationResource *bone_anim_new = *(CBoneAnimationResource **)anim_res_new->BoneAnimation->GetData(i);
		XMMATRIX mtx = GetAnimationMatrix(bone_anim_new, sec, &finished);

		for (int j = 0; j <= (int)BoneArray->PushPos - 1; j++){
			CBoneResource *bone = *(CBoneResource **)BoneArray->GetData(j);
			if (bone_anim_new->TargetBone == bone && bone_anim_new->TargetBone != NULL){
				bone->ChangeFrameCount = change_frame_count;
				bone->PrevJointParamTransformed = mtx;
				bone->ChangeNewAnimation = true;
				bone->ChangeFrameCount = change_frame_count;
				bone->NowChangeFrameCount = 0;
			}
		}
	}

	for (int i = 0; i <= (int)anim_res_prev->BoneAnimation->PushPos - 1; i++){

		CBoneAnimationResource *bone_anim_prev = *(CBoneAnimationResource **)anim_res_prev->BoneAnimation->GetData(i);
		XMMATRIX mtx = GetAnimationMatrix(bone_anim_prev, sec, &finished);

		for (int j = 0; j <= (int)BoneArray->PushPos - 1; j++){
			CBoneResource *bone = *(CBoneResource **)BoneArray->GetData(j);
			if (bone_anim_prev->TargetBone == bone && bone_anim_prev->TargetBone != NULL){
				bone->ChangeFrameCount = change_frame_count;
				bone->PrevJointParamTransformed = mtx;
				bone->ChangeNewAnimation = true;
				bone->ChangeFrameCount = change_frame_count;
				bone->NowChangeFrameCount = 0;
			}
		}
	}

	CurrentAnimationNum = num;

	return true;
}


bool CChaResourceObject::UpdateTransform(){

	//スケール、位置、回転
	TransformMatrix = XMMatrixScaling(Scale.x, Scale.y, Scale.z) * XMMatrixRotationX(ToRadian(Rotation.x)) * XMMatrixRotationY(ToRadian(Rotation.y)) * XMMatrixRotationZ(ToRadian(Rotation.z)) * XMMatrixTranslation(Position.x, Position.y, Position.z);
	NormalTransformMatrix = XMMatrixRotationX(ToRadian(Rotation.x)) * XMMatrixRotationY(ToRadian(Rotation.y)) * XMMatrixRotationZ(ToRadian(Rotation.z));

	if (IsAnimated == false)
		return false;

	if (CurrentAnimationNum < 0 || CurrentAnimationNum >= AnimationList->PushPos)
		return false;

	if (ControlBone->PushPos <= 0)
		return false;

	if (AnimationList->PushPos <= 0)
		return false;

	CAnimationResource *anim_res = *(CAnimationResource **)AnimationList->GetData(CurrentAnimationNum);

	if (AnimationFinished == true && Refrain == false) {
		FrameCount = 0;
	}

	float sec = (float)FrameCount * (float)AnimationSpeed / 50.00f;

	for (int i = 0; i <= ControlBone->PushPos - 1; i++)
		BoneInit(*(CBoneResource **)ControlBone->GetData(i));

	bool anim_finished = false;
	for (int i = 0; i <= (int)BoneArray->PushPos - 1; i++){

		CBoneResource *bone = *(CBoneResource **)BoneArray->GetData(i);
		XMMATRIX mtx = bone->JointParam;

		for (int j = 0; j <= anim_res->BoneAnimation->PushPos - 1; j++){

			int finished = 0;
			CBoneAnimationResource *bone_anim = *(CBoneAnimationResource **)anim_res->BoneAnimation->GetData(j);
			if (bone_anim->TargetBone != NULL && bone_anim->TargetBone == bone){
				mtx = GetAnimationMatrix(bone_anim, sec, &finished);
				if (finished == 1)
					anim_finished = true;
			}
		}

		//現在のアニメーションから新しいアニメーションへ移行中の場合
		if (bone->ChangeNewAnimation == true && AnimationFinished == false){
			bone->NowChangeFrameCount++;
			if (bone->NowChangeFrameCount >= bone->ChangeFrameCount){
				bone->NowChangeFrameCount = 0;
				bone->ChangeFrameCount = 0;
				bone->ChangeNewAnimation = false;
			}
			else{
				float rate = (float)bone->NowChangeFrameCount / (float)bone->ChangeFrameCount;
				mtx = CalcInterPauseLinear(bone->PrevJointParamTransformed, mtx, rate);
			}
		}

		bone->JointParamTransformed = mtx;
	}

	for (int i = 0; i <= ControlBone->PushPos - 1; i++){
		CBoneResource *parent = *(CBoneResource**)ControlBone->GetData(i);
		BoneTransform(parent);
	}

	if (anim_finished == true && Refrain == false){
		AnimationFinished = true;
		return false;
	}

	return true;
}

bool CChaResourceObject::BoneInit(CBoneResource *bone){

	bone->BoneMatrix = XMMatrixIdentity();

	if (bone->ParentBone != NULL){
		bone->JointParamTransformed = bone->JointParam;
	}
	for (int i = 0; i <= (int)bone->ChildBone->PushPos - 1; i++){
		BoneInit(*(CBoneResource **)bone->ChildBone->GetData(i));
	}

	return true;
}
