<file_sep>#include "BoundingSphere.h"

#include <assert.h>
#include "Bounding.h"
#include "BoundingBox.h"
#include "BoundingFrustum.h"
#include "Ray.h"

#include "../Core/Plane.h"
#include "../Core/MathHelper.h"

//////////////////////////////////////////////////////////////////////////
///@brief 생성자
//////////////////////////////////////////////////////////////////////////
BoundingSphere::BoundingSphere( void )
{
	this->Center = Vector3::Zero;
	this->Radius = 0.0f;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
///@param center : 위치 벡터
///@param radius : 반지름 값
//////////////////////////////////////////////////////////////////////////
BoundingSphere::BoundingSphere( Vector3 center, float radius )
{
	assert(radius >= 0.0f);

	this->Center = center;
	this->Radius = radius;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief ==
///@param value : 바운딩 스페어
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool BoundingSphere::operator==( const BoundingSphere& value ) const
{
	if(this->Center == value.Center)
		return (double)this->Radius == (double)value.Radius;
	else
		return false;
}
//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
///@brief !=
///@param value : 바운딩 스페어
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool BoundingSphere::operator!=( const BoundingSphere& value ) const
{
	if (!(this->Center != value.Center))
		return (double)this->Radius != (double)value.Radius;
	else
		return true;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 서포트 매핑
///@param v : 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 BoundingSphere::SupportMapping( Vector3 v )
{
	float num = Radius / v.Length();

	Vector3 result;
	result.X = Center.X + v.X * num;
	result.Y = Center.Y + v.Y * num;
	result.Z = Center.Z + v.Z * num;

	return result;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 두 개의 바운딩 스페어 합침
///@param original : 바운딩 스페어1
///@param additional : 바운딩 스페어2
///@return 결과 바운딩 스페어
//////////////////////////////////////////////////////////////////////////
BoundingSphere BoundingSphere::CreateMerged( BoundingSphere original, BoundingSphere additional )
{
	Vector3 result = additional.Center - original.Center;

	float num1 = result.Length();
	float num2 = original.Radius;
	float num3 = additional.Radius;
	
	if((double)num2 + (double)num3 >= (double)num1)
	{
		if ((double)num2 - (double)num3 >= (double)num1)
			return original;
		else if ((double)num3 - (double)num2 >= (double)num1)
			return additional;
	}

	Vector3 vector3 = result * (1.0f / num1);
	float num4 = MathHelper::Min(-num2, num1 - num3);
	float num5 = (float)(((double)MathHelper::Max(num2, num1 + num3) - (double)num4)* 0.5);
	
	BoundingSphere boundingSphere;
	boundingSphere.Center = original.Center + vector3 * (num5 + num4);
	boundingSphere.Radius = num5;

	return boundingSphere;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 박스로부터 바운딩 스페어 생성
///@param box : 바운딩 박스
///@return 결과 바운딩 스페어
//////////////////////////////////////////////////////////////////////////
BoundingSphere BoundingSphere::CreateFromBoundingBox( BoundingBox box )
{
	BoundingSphere boundingSphere;
	boundingSphere.Center = Vector3::Lerp(box.Min, box.Max, 0.5f);
	
	float result;
	result = Vector3::Distance(box.Min, box.Max);
	boundingSphere.Radius = result * 0.5f;
	
	return boundingSphere;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 박스와의 교차 검사
///@param box : 바운딩 박스
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool BoundingSphere::Intersects( BoundingBox box )
{
	Vector3 result1 = Vector3::Clamp(Center, box.Min, box.Max);
	float result2 = Vector3::DistanceSquared(Center, result1);
	
	if((double)result2 <= (double)Radius * (double)Radius)
		return true;
	else
		return false;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 프러스텀과의 교차 검사
///@param frustum : 바운딩 프러스텀
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool BoundingSphere::Intersects( BoundingFrustum frustum )
{
	bool result;
	frustum.Intersects(*this, result);
	
	return result;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 평면과의 교차 검사
///@param plane : 평면
///@return 교차 결과
//////////////////////////////////////////////////////////////////////////
PlaneIntersectionType BoundingSphere::Intersects( Plane plane )
{
	return plane.Intersects(*this);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 레이와의 교차 검사
///@param ray : 광선
///@return 교차 결과
//////////////////////////////////////////////////////////////////////////
bool BoundingSphere::Intersects( Ray ray, float& result )
{
	return ray.Intersects(*this, result);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 스페어와의 교차 검사
///@param sphere : 바운딩 스페어
///@return 교차 결과
//////////////////////////////////////////////////////////////////////////
bool BoundingSphere::Intersects( BoundingSphere sphere )
{
	float result = Vector3::DistanceSquared(Center, sphere.Center);
	float num1 = Radius;
	float num2 = sphere.Radius;

	if((double)num1 * (double)num1 + 2.0 * (double)num1 * (double)num2 + (double)num2 * (double)num2 <= (double)result)
		return false;
	else
		return true;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 박스 포함 검사
///@param box : 바운<NAME>
///@return 포함 결과
//////////////////////////////////////////////////////////////////////////
ContainmentType BoundingSphere::Contains( BoundingBox box )
{
	if(!box.Intersects(*this))
	{
		return ContainmentType_Disjoint;
	}
	else
	{
		float num = Radius * Radius;
		
		Vector3 vector3;
		vector3.X = Center.X - box.Min.X;
		vector3.Y = Center.Y - box.Max.Y;
		vector3.Z = Center.Z - box.Max.Z;

		if((double)vector3.LengthSquared() > (double)num)
		{
			return ContainmentType_Intersects;
		}
		else
		{
			vector3.X = Center.X - box.Max.X;
			vector3.Y = Center.Y - box.Max.Y;
			vector3.Z = Center.Z - box.Max.Z;
			
			if ((double)vector3.LengthSquared() > (double)num)
			{
				return ContainmentType_Intersects;
			}
			else
			{
				vector3.X = Center.X - box.Max.X;
				vector3.Y = Center.Y - box.Min.Y;
				vector3.Z = Center.Z - box.Max.Z;
				
				if((double)vector3.LengthSquared() > (double)num)
				{
					return ContainmentType_Intersects;
				}
				else
				{
					vector3.X = Center.X - box.Min.X;
					vector3.Y = Center.Y - box.Min.Y;
					vector3.Z = Center.Z - box.Max.Z;

					if((double)vector3.LengthSquared() > (double)num)
					{
						return ContainmentType_Intersects;
					}
					else
					{
						vector3.X = Center.X - box.Min.X;
						vector3.Y = Center.Y - box.Max.Y;
						vector3.Z = Center.Z - box.Min.Z;

						if((double)vector3.LengthSquared() > (double)num)
						{
							return ContainmentType_Intersects;
						}
						else
						{
							vector3.X = Center.X - box.Max.X;
							vector3.Y = Center.Y - box.Max.Y;
							vector3.Z = Center.Z - box.Min.Z;

							if((double)vector3.LengthSquared() > (double)num)
							{
								return ContainmentType_Intersects;
							}
							else
							{
								vector3.X = Center.X - box.Max.X;
								vector3.Y = Center.Y - box.Min.Y;
								vector3.Z = Center.Z - box.Min.Z;

								if((double)vector3.LengthSquared() > (double)num)
								{
									return ContainmentType_Intersects;
								}
								else
								{
									vector3.X = Center.X - box.Min.X;
									vector3.Y = Center.Y - box.Min.Y;
									vector3.Z = Center.Z - box.Min.Z;

									if((double)vector3.LengthSquared() > (double)num)
										return ContainmentType_Intersects;
									else
										return ContainmentType_Contains;
								}
							}
						}
					}
				}
			}
		}
	}
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 프러스텀과의 포함 검사
///@param frustum : 바운딩 프러스텀
///@return 포함 결과
//////////////////////////////////////////////////////////////////////////
ContainmentType BoundingSphere::Contains( BoundingFrustum frustum )
{
	if(!frustum.Intersects(*this))
	{
		return ContainmentType_Disjoint;
	}
	else
	{
		float num = Radius * Radius;
		
		for(int i = 0; i < 8; i++)
		{
			Vector3 vector3_1 = frustum.cornerArray[i];
			
			Vector3 vector3_2;
			vector3_2.X = vector3_1.X - Center.X;
			vector3_2.Y = vector3_1.Y - Center.Y;
			vector3_2.Z = vector3_1.Z - Center.Z;

			if((double)vector3_2.LengthSquared() > (double)num)
				return ContainmentType_Intersects;
		}
		
		return ContainmentType_Contains;
	}
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 위치 벡터의 포함 검사
///@param point : 위치 벡터
///@return 포함 결과
//////////////////////////////////////////////////////////////////////////
ContainmentType BoundingSphere::Contains( Vector3 point )
{
	if ((double)Vector3::DistanceSquared(point, Center) >= (double)Radius * (double)Radius)
		return ContainmentType_Disjoint;
	else
		return ContainmentType_Contains;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 스페어의 포함 여부 검사
///@param sphere : 바운딩 스페어
///@return 포함 결과
//////////////////////////////////////////////////////////////////////////
ContainmentType BoundingSphere::Contains( BoundingSphere sphere )
{
	float result = Vector3::Distance(Center, sphere.Center);
	float num1 = Radius;
	float num2 = sphere.Radius;
	
	if((double)num1 + (double)num2 < (double)result)
		return ContainmentType_Disjoint;
	else if((double)num1 - (double)num2 < (double)result)
		return ContainmentType_Intersects;
	else
		return ContainmentType_Contains;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 매트릭스에 의한 바운딩 스페어 변환
///@param matrix : 매트릭스
///@return 결과 바운딩 스페어
//////////////////////////////////////////////////////////////////////////
BoundingSphere BoundingSphere::Transform( Matrix matrix )
{
	BoundingSphere boundingSphere;
	boundingSphere.Center = Vector3::Transform(Center, matrix);

	float num = MathHelper::Max((float)(
		(double)matrix.M11 * (double)matrix.M11 + (double)matrix.M12 * (double)matrix.M12 + (double)matrix.M13 * (double)matrix.M13), 
		MathHelper::Max((float)((double)matrix.M21 * (double)matrix.M21 + (double)matrix.M22 * (double)matrix.M22 + (double)matrix.M23 * (double)matrix.M23), 
		(float)((double)matrix.M31 * (double)matrix.M31 + (double)matrix.M32 * (double)matrix.M32 + (double)matrix.M33 * (double)matrix.M33)));

	boundingSphere.Radius = Radius * (float)sqrt((double)num);
	
	return boundingSphere;
}<file_sep>#pragma once

class ModelTool : public Execute
{
public:
	ModelTool(ExecuteValues* values);
	~ModelTool();

	void Update();

	void PreRender() {}
	void Render();
	void PostRender();

	void ResizeScreen() {}


private:
	class GameSkyBox* skyBox;
	class GameWorld* world;
	class GameAnimationModel* grund;
	class GamePlayer* player;
};<file_sep>#include "stdafx.h"
#include "GizmoComponent.h"
#include "./Framework/Core/Matrix.h"
#include "./Framework/Core/Vector3.h"
#include "./Framework/Bounding/Ray.h"
#include "./Framework/Core/Plane.h"

#include "Gizmo.h"


Gizmo::GizmoComponent::GizmoComponent(ExecuteValues* values)
	:values(values)
{
	Init();
}

Gizmo::GizmoComponent::~GizmoComponent()
{
	SAFE_RELEASE(rasterizer[0]);
	SAFE_RELEASE(rasterizer[1]);

	SAFE_RELEASE(depthStencilState[0]);
	SAFE_RELEASE(depthStencilState[1]);

	for (Gizmo* gizmo : quads)
		SAFE_DELETE(gizmo);
	for (Gizmo* gizmo : lines)
		SAFE_DELETE(gizmo);
	for (Gizmo* gizmo : scales)
		SAFE_DELETE(gizmo);
	for (Gizmo* gizmo : rotates)
		SAFE_DELETE(gizmo);
	for (Gizmo* gizmo : translates)
		SAFE_DELETE(gizmo);
	for (Gizmo* gizmo : boxes)
		SAFE_DELETE(gizmo);
	for (Gizmo* gizmo : spheres)
		SAFE_DELETE(gizmo);
}

D3DXMATRIX Gizmo::GizmoComponent::TransformDelta()
{
	scaleDelta *= SCALE_WEIGHT;
	D3DXMATRIX S, T, T2;

	D3DXMatrixIdentity(&S);
	D3DXMatrixIdentity(&T);
	D3DXMatrixIdentity(&T2);

	//Inverse
	D3DXMATRIX invRot;
	D3DXMatrixInverse(&invRot, NULL, &rotMat);

	D3DXMATRIX invPos;
	D3DXMatrixTranslation(&T2, position.x, position.y, position.z);
	D3DXMatrixInverse(&invPos, NULL, &T2);

	D3DXVECTOR3 tempScale = { 1,1,1 };
	if (scaleDelta != D3DXVECTOR3(0, 0, 0))
	{
		tempScale += scaleDelta;
		D3DXMatrixScaling(&S, tempScale.x, tempScale.y, tempScale.z);

		//축방향으로 스케일하기 위해
		S = invPos*invRot*S*rotMat*T2;
	}

	D3DXMATRIX identity;
	D3DXMatrixIdentity(&identity);
	if (rotationDelta != identity)
	{
		//모델 중심으로 회전
		rotationDelta = invPos*rotationDelta*T2;
	}

	if (translationDelta != D3DXVECTOR3(0, 0, 0))
	{
		//이동값은 방향구해서 가져왔으니 바로계산
		D3DXMatrixTranslation(&T, translationDelta.x, translationDelta.y, translationDelta.z);
		translationDelta = { 0,0,0 };
	}

	D3DXMATRIX ret = S* rotationDelta* T;
	D3DXMatrixIdentity(&rotationDelta);
	return ret;

}

void Gizmo::GizmoComponent::Init()
{
	{
		D3D11_RASTERIZER_DESC desc;
		States::GetRasterizerDesc(&desc);
		States::CreateRasterizer(&desc, &rasterizer[0]);

		desc.CullMode = D3D11_CULL_NONE;
		States::CreateRasterizer(&desc, &rasterizer[1]);
	}

	{
		D3D11_DEPTH_STENCIL_DESC desc;
		States::GetDepthStencilDesc(&desc);
		States::CreateDepthStencil(&desc, &depthStencilState[0]);

		desc.DepthEnable = false;
		States::CreateDepthStencil(&desc, &depthStencilState[1]);
	}

	target = NULL;
	D3DXMatrixIdentity(&gizmoWorld);
	D3DXMatrixIdentity(&outsideWorld);

	D3DXMatrixIdentity(&scaleMat);
	D3DXMatrixIdentity(&rotMat);
	D3DXMatrixIdentity(&posMat);

	D3DXQuaternionIdentity(&rotQuat);

	scale = { 1,1,1 };
	rotate = { 0,0,0 };
	position = { 0,0,0 };

	ResetMouseValues();
	ResetDeltas();

	bMousePressed = false;
	bDrawBounding = false;
	activeMode = EGizmoMode::Translate;
	activeAxis = EGizmoAxis::None;

	colors[0] = D3DXCOLOR(1, 0, 0, 1);
	colors[1] = D3DXCOLOR(0, 1, 0, 1);
	colors[2] = D3DXCOLOR(0, 0, 1, 1);

	geometryWorld[0] = Matrix::CreateWorld(Vector3(LINE_LENGTH, 0, 0), Vector3::Left, Vector3::Up).ToD3DXMATRIX();
	geometryWorld[1] = Matrix::CreateWorld(Vector3(0, LINE_LENGTH, 0), Vector3::Down, Vector3::Left).ToD3DXMATRIX();
	geometryWorld[2] = Matrix::CreateWorld(Vector3(0, 0, LINE_LENGTH), Vector3::Forward, Vector3::Up).ToD3DXMATRIX();

	Create2D();
	Create3D();
	CreateBoundings();
}

void Gizmo::GizmoComponent::MouseCollision()
{
	float* distance = NULL;
	float sphereDist = 0;
	Ray ray = ConvertMouseToRay(gizmoWorld);

	if (xAxisBox->Intersects(ray, distance) || xSphere->Intersects(ray, sphereDist))
		activeAxis = EGizmoAxis::X;
	else if (yAxisBox->Intersects(ray, distance) || ySphere->Intersects(ray, sphereDist))
		activeAxis = EGizmoAxis::Y;
	else if (zAxisBox->Intersects(ray, distance) || zSphere->Intersects(ray, sphereDist))
		activeAxis = EGizmoAxis::Z;
	else if (xyAxisBox->Intersects(ray, distance))
		activeAxis = EGizmoAxis::XY;
	else if (xzAxisBox->Intersects(ray, distance))
		activeAxis = EGizmoAxis::ZX;
	else if (yzAxisBox->Intersects(ray, distance))
		activeAxis = EGizmoAxis::YZ;
	else
		activeAxis = EGizmoAxis::None;

	SAFE_DELETE(distance);

	//highlight color
	ResetHighlight();
	switch (activeAxis)
	{
	case EGizmoAxis::None:
		break;
	case EGizmoAxis::X:
	case EGizmoAxis::Y:
	case EGizmoAxis::Z:
	{
		int index = (int)activeAxis;
		lines[index]->bHighlight = true;
		scales[index]->bHighlight = true;
		rotates[index]->bHighlight = true;
		translates[index]->bHighlight = true;
	}
	break;
	case EGizmoAxis::XY:
		quads[0]->bHighlight = true;
		break;
	case EGizmoAxis::ZX:
		quads[1]->bHighlight = true;
		break;
	case EGizmoAxis::YZ:
		quads[2]->bHighlight = true;
		break;
	}
}

void Gizmo::GizmoComponent::Pressing()
{
	D3DXVECTOR3 tempPos;
	D3DXMATRIX invRot;
	D3DXMatrixInverse(&invRot, NULL, &rotMat);
	D3DXVec3TransformCoord(&tempPos, &position, &invRot);
	Vector3 tempPos2 = { tempPos.x, tempPos.y, tempPos.z };

	//Collision Plane
	Plane planeXY = Plane(Vector3::Forward, -tempPos2.Z);
	Plane planeYZ = Plane(Vector3::Left, tempPos2.X);
	Plane planeZX = Plane(Vector3::Down, tempPos2.Y);

	Ray ray = ConvertMouseToRay(rotMat);

	float value = 0;
	lastIntersectPosition = intersectPosition;
	switch (activeAxis)
	{
	case EGizmoAxis::None:
		break;
	case EGizmoAxis::XY:
	case EGizmoAxis::X:
		if (ray.Intersects(planeXY, value))
		{
			intersectPosition = (ray.Position + (ray.Direction * value));
			if (lastIntersectPosition != Vector3::Zero)
			{
				delta = intersectPosition - lastIntersectPosition;
			}
			delta = activeAxis == EGizmoAxis::X ? Vector3(delta.X, 0, 0) : Vector3(delta.X, delta.Y, 0);
		}
		break;
	case EGizmoAxis::Z:
	case EGizmoAxis::YZ:
	case EGizmoAxis::Y:
		if (ray.Intersects(planeYZ, value))
		{
			intersectPosition = (ray.Position + (ray.Direction * value));
			if (lastIntersectPosition != Vector3::Zero)
			{
				delta = intersectPosition - lastIntersectPosition;
			}
			switch (activeAxis)
			{
			case EGizmoAxis::Y:
				delta = Vector3(0, delta.Y, 0);
				break;
			case EGizmoAxis::Z:
				delta = Vector3(0, 0, delta.Z);
				break;
			default:
				delta = Vector3(0, delta.Y, delta.Z);
				break;
			}
		}
		break;
	case EGizmoAxis::ZX:
		if (ray.Intersects(planeZX, value))
		{
			intersectPosition = (ray.Position + (ray.Direction * value));
			if (lastIntersectPosition != Vector3::Zero)
			{
				delta = intersectPosition - lastIntersectPosition;
			}
			delta = Vector3(delta.X, 0, delta.Z);
		}
		break;
	}

	//ActiveMode

	switch (activeMode)
	{
	case EGizmoMode::Scale:
	{
		scaleDelta += D3DXVECTOR3(delta.X, delta.Y, delta.Z);
		D3DXMATRIX deltaTranslation;
		D3DXMatrixTranslation(&deltaTranslation, delta.X, delta.Y, delta.Z);
		switch (activeAxis)
		{
		case EGizmoAxis::X:
		case EGizmoAxis::Y:
		case EGizmoAxis::Z:
			int index = (int)activeAxis;
			lines[index]->vertexData[1].position += scaleDelta;
			geometryWorld[index] *= deltaTranslation;
			lines[index]->UpdateVertexData();
			break;
		}
	}
	break;

	case EGizmoMode::Rotate:
	{
		lastMousePos = curMousePos;
		curMousePos = Mouse::Get()->GetPosition();
		float deltaX = 0;
		if (lastMousePos != D3DXVECTOR3(0, 0, 0))
			deltaX = curMousePos.x - lastMousePos.x;

		D3DXVECTOR3 rotVec = D3DXVECTOR3(
			Math::ToRadian(deltaX * ROTATE_WEIGHT), Math::ToRadian(deltaX * ROTATE_WEIGHT), Math::ToRadian(deltaX * ROTATE_WEIGHT));

		D3DXMATRIX rot, tempRot;
		D3DXMatrixIdentity(&rot);
		rot = rotMat;

		D3DXVECTOR3 vecX, vecY, vecZ;
		vecX = D3DXVECTOR3(rot._11, rot._12, rot._13);
		vecY = D3DXVECTOR3(rot._21, rot._22, rot._23);
		vecZ = D3DXVECTOR3(rot._31, rot._32, rot._33);

		D3DXQUATERNION q;
		D3DXQuaternionIdentity(&q);
		switch (activeAxis)
		{
		case EGizmoAxis::X:
			D3DXMatrixRotationAxis(&tempRot, &vecX, rotVec.x);
			D3DXQuaternionRotationAxis(&q, &vecX, rotVec.x);
			break;
		case EGizmoAxis::Y:
			D3DXMatrixRotationAxis(&tempRot, &vecY, rotVec.y);
			D3DXQuaternionRotationAxis(&q, &vecY, rotVec.y);
			break;
		case EGizmoAxis::Z:
			D3DXMatrixRotationAxis(&tempRot, &vecZ, rotVec.z);
			D3DXQuaternionRotationAxis(&q, &vecZ, rotVec.z);
			break;
		}

		rotQuat *= q;
		D3DXMatrixRotationQuaternion(&rotationDelta, &q);
		D3DXMatrixRotationQuaternion(&rotMat, &rotQuat);
	}
	break;

	case EGizmoMode::Translate:
	{
		D3DXVECTOR3 temp, temp2;
		temp2 = { delta.X, delta.Y, delta.Z };
		D3DXVec3TransformCoord(&temp, &temp2, &rotMat);
		position += temp;
		translationDelta += temp;
	}
	break;
	}
}

void Gizmo::GizmoComponent::Update()
{
	//TargetTransform
	if (target != NULL)
	{
		D3DXMATRIX targetMat = *target;
		D3DXMATRIX deltaMat = TransformDelta();

		targetMat *= deltaMat;
		*target = targetMat;
	}

	//ResizeWorldScale
	//TODO: 모델거리에 비례해서 기즈모 크기조절
	ResizeWorldScale();

	if (Keyboard::Get()->Down('1'))
		activeMode = EGizmoMode::Translate;
	if (Keyboard::Get()->Down('2'))
		activeMode = EGizmoMode::Rotate;
	if (Keyboard::Get()->Down('3'))
		activeMode = EGizmoMode::Scale;

	//MouseInput
	if (Mouse::Get()->Down(0))
	{
		MouseCollision();
		bMousePressed = true;
	}
	if (bMousePressed)
	{
		ResetDeltas();
		Pressing();
	}
	if (Mouse::Get()->Up(0))
	{
		bMousePressed = false;
		ResetMouseValues();
		ResetDeltas();
		ResetHighlight();
		ResetScaleGizmo();
	}

	//GizmoWorld
	D3DXMatrixScaling(&scaleMat, scale.x, scale.y, scale.z);
	D3DXMatrixTranslation(&posMat, position.x, position.y, position.z);

	gizmoWorld = scaleMat*rotMat*posMat;
}

void Gizmo::GizmoComponent::Render()
{
	D3D::GetDC()->OMSetDepthStencilState(depthStencilState[1], 1);
	D3D::GetDC()->RSSetState(rasterizer[1]);
	{
		Draw2D();
		Draw3D();

		if (bDrawBounding == true)
			DrawBounding();
	}
	D3D::GetDC()->RSSetState(rasterizer[0]);
	D3D::GetDC()->OMSetDepthStencilState(depthStencilState[0], 1);
}

void Gizmo::GizmoComponent::PostRender()
{
	ImGui::Begin("Gizmo");

	ImGui::Checkbox("DrawBounding", &bDrawBounding);
	ImGui::InputFloat3("Intersect Position", (float*)&intersectPosition);
	ImGui::InputFloat3("LastIntersect Position", (float*)&lastIntersectPosition);
	ImGui::InputFloat3("Delta", (float*)&delta);
	ImGui::End();
}

void Gizmo::GizmoComponent::Draw2D()
{
	for (size_t i = 0; i < quads.size(); i++)
	{
		if (activeMode == EGizmoMode::Translate)
		{
			quads[i]->rootWorld = gizmoWorld;
			quads[i]->color = colors[i];
			quads[i]->Render();
		}
	}

	for (size_t i = 0; i < lines.size(); i++)
	{
		lines[i]->rootWorld = gizmoWorld;
		lines[i]->color = colors[i];
		lines[i]->Render();
	}
}

void Gizmo::GizmoComponent::Draw3D()
{
	for (int i = 0; i < 3; i++) //(order: x, y, z)
	{
		Gizmo* activeModel;
		switch (activeMode)
		{
		case EGizmoMode::Translate:
			activeModel = translates[i];
			break;
		case EGizmoMode::Rotate:
			activeModel = rotates[i];
			break;
		case EGizmoMode::Scale:
			activeModel = scales[i];
			break;
		}

		activeModel->rootWorld = gizmoWorld;
		activeModel->localWorld = geometryWorld[i];
		activeModel->color = colors[i];

		activeModel->Render();
	}
}

void Gizmo::GizmoComponent::DrawBounding()
{
	for (Gizmo* gizmo : boxes)
	{
		gizmo->rootWorld = gizmoWorld;
		gizmo->Render();
	}
	for (Gizmo* gizmo : spheres)
	{
		gizmo->rootWorld = gizmoWorld;
		gizmo->Render();
	}

}

void Gizmo::GizmoComponent::Create2D()
{
	//Quads
	float halfLineOffset = LINE_OFFSET / 2;
	quads.push_back(Gizmos::Quad(D3DXVECTOR3(halfLineOffset, halfLineOffset, 0), D3DXVECTOR3(0, 0, -1), D3DXVECTOR3(0, 1, 0), LINE_OFFSET,
		LINE_OFFSET)); //XY
	quads.push_back(Gizmos::Quad(D3DXVECTOR3(halfLineOffset, 0, halfLineOffset), D3DXVECTOR3(0, 1, 0), D3DXVECTOR3(1, 0, 0), LINE_OFFSET,
		LINE_OFFSET)); //XZ
	quads.push_back(Gizmos::Quad(D3DXVECTOR3(0, halfLineOffset, halfLineOffset), D3DXVECTOR3(1, 0, 0), D3DXVECTOR3(0, 1, 0), LINE_OFFSET,
		LINE_OFFSET)); //ZY 

					   //Lines
	lines.push_back(Gizmos::Line({ 0,0,0 }, { LINE_LENGTH, 0,0 }));
	lines.push_back(Gizmos::Line({ 0,0,0 }, { 0, LINE_LENGTH,0 }));
	lines.push_back(Gizmos::Line({ 0,0,0 }, { 0, 0,LINE_LENGTH }));
}

void Gizmo::GizmoComponent::Create3D()
{
	for (size_t i = 0; i < 3; i++)
	{
		scales.push_back(Gizmos::Scale());
		rotates.push_back(Gizmos::Rotate());
		translates.push_back(Gizmos::Translate());
	}
}

void Gizmo::GizmoComponent::CreateBoundings()
{
	//Boxes
	const float MULTI_AXIS_THICKNESS = 0.05f;
	const float SINGLE_AXIS_THICKNESS = 0.2f;

	xAxisBox = new BoundingBox(Vector3(LINE_OFFSET, 0, 0),
		Vector3(LINE_OFFSET + LINE_LENGTH, SINGLE_AXIS_THICKNESS, SINGLE_AXIS_THICKNESS));

	boxes.push_back(Gizmos::WireCube({ LINE_OFFSET, 0, 0 },
	{ LINE_OFFSET + LINE_LENGTH, SINGLE_AXIS_THICKNESS, SINGLE_AXIS_THICKNESS }));

	yAxisBox = new BoundingBox(Vector3(0, LINE_OFFSET, 0),
		Vector3(SINGLE_AXIS_THICKNESS, LINE_OFFSET + LINE_LENGTH, SINGLE_AXIS_THICKNESS));

	boxes.push_back(Gizmos::WireCube({ 0, LINE_OFFSET, 0 },
	{ SINGLE_AXIS_THICKNESS, LINE_OFFSET + LINE_LENGTH, SINGLE_AXIS_THICKNESS }));

	zAxisBox = new BoundingBox(Vector3(0, 0, LINE_OFFSET),
		Vector3(SINGLE_AXIS_THICKNESS, SINGLE_AXIS_THICKNESS, LINE_OFFSET + LINE_LENGTH));

	boxes.push_back(Gizmos::WireCube({ 0, 0, LINE_OFFSET },
	{ SINGLE_AXIS_THICKNESS, SINGLE_AXIS_THICKNESS, LINE_OFFSET + LINE_LENGTH }));

	xzAxisBox = new BoundingBox(Vector3::Zero,
		Vector3(LINE_OFFSET, MULTI_AXIS_THICKNESS, LINE_OFFSET));

	boxes.push_back(Gizmos::WireCube({ 0, 0, 0 },
	{ LINE_OFFSET, MULTI_AXIS_THICKNESS, LINE_OFFSET }));

	xyAxisBox = new BoundingBox(Vector3::Zero,
		Vector3(LINE_OFFSET, LINE_OFFSET, MULTI_AXIS_THICKNESS));

	boxes.push_back(Gizmos::WireCube({ 0, 0, 0 },
	{ LINE_OFFSET, LINE_OFFSET, MULTI_AXIS_THICKNESS }));

	yzAxisBox = new BoundingBox(Vector3::Zero,
		Vector3(MULTI_AXIS_THICKNESS, LINE_OFFSET, LINE_OFFSET));

	boxes.push_back(Gizmos::WireCube({ 0, 0, 0 },
	{ MULTI_AXIS_THICKNESS, LINE_OFFSET, LINE_OFFSET }));

	//Spheres
	const float RADIUS = 1.0f;
	D3DXVECTOR3 position = lines[0]->vertexData[1].position;
	Vector3 temp = { position.x, position.y, position.z };
	xSphere = new BoundingSphere(temp, RADIUS);
	spheres.push_back(Gizmos::WireSphere(position, RADIUS));

	position = lines[1]->vertexData[1].position;
	temp = { position.x, position.y, position.z };
	ySphere = new BoundingSphere(temp, RADIUS);
	spheres.push_back(Gizmos::WireSphere(position, RADIUS));

	position = lines[2]->vertexData[1].position;
	temp = { position.x, position.y, position.z };
	zSphere = new BoundingSphere(temp, RADIUS);
	spheres.push_back(Gizmos::WireSphere(position, RADIUS));
}

void Gizmo::GizmoComponent::ResetHighlight()
{
	for (Gizmo* gizmo : quads)
		gizmo->bHighlight = false;
	for (Gizmo* gizmo : lines)
		gizmo->bHighlight = false;
	for (Gizmo* gizmo : scales)
		gizmo->bHighlight = false;
	for (Gizmo* gizmo : rotates)
		gizmo->bHighlight = false;
	for (Gizmo* gizmo : translates)
		gizmo->bHighlight = false;
}

void Gizmo::GizmoComponent::ResetMouseValues()
{
	intersectPosition = lastIntersectPosition = delta = Vector3::Zero;
	curMousePos = lastMousePos = { 0,0,0 };
}

void Gizmo::GizmoComponent::ResetDeltas()
{
	translationDelta = scaleDelta = { 0,0,0 };
	D3DXMatrixIdentity(&rotationDelta);
}

void Gizmo::GizmoComponent::ResetScaleGizmo()
{
	geometryWorld[0] = Matrix::CreateWorld(Vector3(LINE_LENGTH, 0, 0), Vector3::Left, Vector3::Up).ToD3DXMATRIX();
	geometryWorld[1] = Matrix::CreateWorld(Vector3(0, LINE_LENGTH, 0), Vector3::Down, Vector3::Left).ToD3DXMATRIX();
	geometryWorld[2] = Matrix::CreateWorld(Vector3(0, 0, LINE_LENGTH), Vector3::Forward, Vector3::Up).ToD3DXMATRIX();

	lines[0]->vertexData[1].position = { LINE_LENGTH, 0,0 };
	lines[1]->vertexData[1].position = { 0, LINE_LENGTH,0 };
	lines[2]->vertexData[1].position = { 0, 0,LINE_LENGTH };

	for (size_t i = 0; i < lines.size(); i++)
	{
		lines[i]->UpdateVertexData();
	}
}

Ray Gizmo::GizmoComponent::ConvertMouseToRay(D3DXMATRIX& world)
{
	//mouse pos, dir
	D3DXVECTOR3 start;
	values->MainCamera->GetPosition(&start);
	D3DXVECTOR3 dir = values->MainCamera->GetDirection(values->Viewport, values->Perspective);

	//inverse
	D3DXMATRIX invMat;
	D3DXMatrixInverse(&invMat, NULL, &world);
	D3DXVec3TransformCoord(&start, &start, &invMat);
	D3DXVec3TransformNormal(&dir, &dir, &invMat);

	//ray
	Ray ray = Ray(Vector3(start.x, start.y, start.z), Vector3(dir.x, dir.y, dir.z));
	return ray;
}

void Gizmo::GizmoComponent::ResizeWorldScale()
{
	if (target != NULL)
	{
		D3DXVECTOR3 targetPos, cameraPos, distance;
		targetPos = { target->_41, target->_42, target->_43 };
		values->MainCamera->GetPosition(&cameraPos);
		distance = targetPos - cameraPos;

		float scaleValue = D3DXVec3Length(&distance);
		scaleValue /= RESIZE_RATIO;
		scale = { scaleValue,scaleValue,scaleValue };
	}
}
<file_sep>#include "stdafx.h"
#include "ModelTool.h"
#include "../Objects/GameAnimationModel.h"
#include "../Objects/ToolsModel.h"
#include "../Model/ModelAnimPlayer.h"
#include "../Objects/Gizmo.h"
#include "../Objects/GizmoComponent.h"
#include "../Fbx/Exporter.h"


ModelTool::ModelTool(ExecuteValues * values)
	: Execute(values)
	, player(NULL)
	, currentSelectBone(-1)
{
	wstring matFile = L"";
	wstring meshFile = L"";

	ExportModel();

	//Grund
	matFile = Models + L"RPG/Character.material";
	meshFile = Models + L"RPG/Character.mesh";
	player = new ToolsModel(Models + L"RPG/", matFile, meshFile);
	player->AddClip(Models + L"RPG/Attack-Kick-L1.anim");
	component = new Gizmo::GizmoComponent(values);
}

ModelTool::~ModelTool()
{
	SAFE_DELETE(player);
}

void ModelTool::Update()
{
	if (player != NULL) player->Update();
	if (currentSelectBone != -1)component->Update();
}

void ModelTool::Render()
{
	if (player != NULL) player->Render();
	if (currentSelectBone != -1)component->Render();
}

void ModelTool::PostRender()
{
	if (values->GuiSettings->bShowModelWindow == true)
	{
		ImGui::Begin("Model Info", &values->GuiSettings->bShowModelWindow);
		if (ImGui::CollapsingHeader("ModelBone"))
		{
			
			ImGuiStyle& style = ImGui::GetStyle();
			style.IndentSpacing = 15.0f;
			
			CreateModelTrees(player->GetModel()->Bone(1));

			
		}
		if (ImGui::CollapsingHeader("SelectedBone"))
		{
			if (currentSelectBone != -1)
			{
				ModelBone* currentSelectedBone = player->GetModel()->Bone(currentSelectBone);
				//string current = String::ToString(currentSelectedBone->Name());
				ImGui::Text(String::ToString(currentSelectedBone->Name()).c_str());
				
			}
		}

		if (ImGui::CollapsingHeader("Animation"))
		{
			ControlAnimPlayer();
		}
		
		ImGui::End();
	}
}

void ModelTool::CreateModelTrees(ModelBone * bone)
{
	string name = String::ToString(bone->Name());
	UINT childCount = bone->ChildCount();
	int index = bone->Index();

	string sNumber = to_string(index) + ". ";
	string sNumName = sNumber + name;

	const char* cName = name.c_str();
	const char* cNumber = sNumber.c_str();
	const char* cNumberName = sNumName.c_str();


	if (childCount == 0)
	{
		ImGui::Indent();
		if (ImGui::Selectable(cNumberName))
			currentSelectBone = index;
		ImGui::Unindent();
	}
	else
	{
		if (ImGui::TreeNodeEx(cNumber, ImGuiTreeNodeFlags_OpenOnArrow))
		{
			ImGui::SameLine();
			if (ImGui::Selectable(cName))
			{
				
				currentSelectBone = index;
				targetMat = player->GetModel()->Bone(currentSelectBone)->AbsoluteTransform();
				D3DXVECTOR3 pos = { targetMat._41,targetMat._42,targetMat._43 };
				component->Position(pos);
				component->SetTarget(&player->GetModel()->Bone(index)->Transform());
			}

			for (size_t i = 0; i < childCount; i++)
			{
				ModelBone* child = bone->Child(i);
				CreateModelTrees(child);
			}
			ImGui::TreePop();
		}
	}
}

void ModelTool::ControlAnimPlayer()
{
}



D3DXMATRIX ModelTool::reculsiveBone_Transform(int index)
{
	D3DXMATRIX result;
	result = player->GetModel()->Bone(index)->Transform();
	if (player->GetModel()->Bone(index)->Parent() != NULL)
	{
		result = result* player->GetModel()->Bone(index)->Parent()->Transform() ;
	}
	return result;
}

void ModelTool::ExportModel()
{
	

	//Fbx::Exporter* exporter = new Fbx::Exporter(Assets + L"RPG_Character/RPG-Character.FBX");
	//exporter->ExportMaterial(Models + L"RPG/", L"Character");
	//exporter->ExportMeshData(Models + L"RPG/", L"Character");
	

	Fbx::Exporter* exporter = new Fbx::Exporter(Assets + L"RPG_Character/RPG-Character@Unarmed-Attack-Kick-L1.FBX");	
	exporter->ExportAnimation(Models + L"RPG/", L"Attack-Kick-L1");
	SAFE_DELETE(exporter);
	exporter = new Fbx::Exporter(Assets + L"RPG_Character/RPG-Character@Unarmed-Attack-Kick-R1.FBX");
	exporter->ExportAnimation(Models + L"RPG/", L"Attack-Kick-R1");
	SAFE_DELETE(exporter);
}

<file_sep>#include "MathHelper.h"

#include <math.h>
#include "Vector3.h"

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

const float MathHelper::E = 2.718282f;
const float MathHelper::Log2E = 1.442695f;
const float MathHelper::Log10E = 0.4342945f;
const float MathHelper::Pi = 3.141593f;
const float MathHelper::TwoPi = 6.283185f;
const float MathHelper::PiOver2 = 1.570796f;
const float MathHelper::PiOver4 = 0.7853982f;
const float MathHelper::Epsilon = 1E-6f;

#pragma warning( disable : 4146)
const int MathHelper::IntMinValue = -2147483648;
const int MathHelper::IntMaxValue = 2147483647;
const float MathHelper::FloatMinValue = -3.402823E+38f;
const float MathHelper::FloatMaxValue = 3.402823E+38f;
#pragma warning( default : 4146)

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


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
//////////////////////////////////////////////////////////////////////////
MathHelper::MathHelper( void )
{
	
}
//////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////
///@brief 반올림
///@param value : 값
///@return : 결과 값
//////////////////////////////////////////////////////////////////////////
double MathHelper::Round( double value )
{
	return Round(value, 0);
}
//////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////
///@brief 반올림
///@param value : 값
///@param position : 올림 자릿수
///@return : 결과
//////////////////////////////////////////////////////////////////////////
double MathHelper::Round( double value, int position )
{
	double temp;
	temp = value * pow(10.0, position); //원하는 소수점 자리만큼의 10의 누승
	temp = floor(temp + 0.5); //0.5를 더해서 가장 가까운 낮은값을 찾음( ex=floor(0.2+0.5)->1.0, floor(0.7+0.5)->1.0f)
	temp *= pow(10.0, -position); //역승해 원값으로 돌림

	return temp;
}
//////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////
///@brief 절대값
///@param value : 값
///@return 결과
//////////////////////////////////////////////////////////////////////////
int MathHelper::Abs( int value )
{
	if(value >= 0)
		return value;
	else
		return -value;
}
//////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////
///@brief 절대값
///@param value : 값
///@return 결과
//////////////////////////////////////////////////////////////////////////
float MathHelper::Abs( float value )
{
	if(value >= 0)
		return value;
	else
		return -value;
}
//////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////
///@brief 절대값
///@param value : 값
///@return 결과
//////////////////////////////////////////////////////////////////////////
double MathHelper::Abs( double value )
{
	if(value >= 0)
		return value;
	else
		return -value;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 각 -> 라디안
///@param degree : 각도
///@return 결과
//////////////////////////////////////////////////////////////////////////
float MathHelper::ToRadians( float degrees )
{
	return degrees * 0.01745329f;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 라디안 -> 각
///@param radians : 라디안
///@return 결과
//////////////////////////////////////////////////////////////////////////
float MathHelper::ToDegrees( float radians )
{
	return radians * 57.29578f;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 두 실수의 거리
///@param value1 : 값1
///@param value2 : 값2
///@return 결과
//////////////////////////////////////////////////////////////////////////
float MathHelper::Distance( float value1, float value2 )
{
	return Abs(value1 - value2);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 두 실수 중 작은 값
///@param value1 : 값1
///@param value2 : 값2
///@return 결과
//////////////////////////////////////////////////////////////////////////
float MathHelper::Min( float value1, float value2 )
{
	return value1 > value2 ? value2 : value1;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 두 실수 중 큰 값
///@param value1 : 값1
///@param value2 : 값2
///@return 결과
//////////////////////////////////////////////////////////////////////////
float MathHelper::Max( float value1, float value2 )
{
	return value1 > value2 ? value1 : value2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 값 비교
///@param value : 값
///@param min : 최소값
///@param max : 최대값
///@return 값이 최대값보다 크면 최대값, 최소값보다 작으면 최소값, 아니면 원래 값
//////////////////////////////////////////////////////////////////////////
float MathHelper::Clamp( float value, float min, float max )
{
	value = (double) value > (double) max ? max : value;
	value = (double) value < (double) min ? min : value;

	return value;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 선형보간
///@param value1 : 값1
///@param value12: 값2
///@param amount : 보간값
///@return 결과
//////////////////////////////////////////////////////////////////////////
float MathHelper::Lerp( float value1, float value2, float amount )
{
	return value1 + (value2 - value1) * amount;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 부드럽게(점진적으로?) 보간
///@param value1 : 값1
///@param value12: 값2
///@param amount : 보간값
///@return 결과
//////////////////////////////////////////////////////////////////////////
float MathHelper::SmoothStep( float value1, float value2, float amount )
{
	float num = Clamp(amount, 0.0f, 1.0f);
    
	return Lerp(value1, value2, (float)((double)num * (double)num * (3.0 - 2.0 * (double)num)));
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 카트뮬-롬 보간
///@param value1 : 값1
///@param value2 : 값2
///@param value3 : 값3
///@param value4 : 값4
///@param amount : 보간값
///@return 결과
//////////////////////////////////////////////////////////////////////////
float MathHelper::CatmullRom( float value1, float value2, float value3, float value4, float amount )
{
	float num1 = amount * amount;
	float num2 = amount * num1;

	return (float)(0.5 * (2.0 * (double)value2 + (-(double)value1 + (double)value3)* (double)amount + (2.0 * (double)value1 - 5.0 * (double)value2 + 4.0 * (double)value3 - (double)value4)* (double)num1 + (-(double)value1 + 3.0 * (double)value2 - 3.0 * (double)value3 + (double)value4)* (double)num2));
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 에르미트 보간
///@param value1 : 값1
///@param tangent1 : 탄젠트1
///@param value2 : 값2
///@param tangent2 : 탄젠트2
///@param amount : 보간값
///@return 결과
//////////////////////////////////////////////////////////////////////////
float MathHelper::Hermite( float value1, float tangent1, float value2, float tangent2, float amount )
{
	float num1 = amount;
	float num2 = num1 * num1;
	float num3 = num1 * num2;
	float num4 = (float)(2.0 * (double)num3 - 3.0 * (double)num2 + 1.0);
	float num5 = (float)(-2.0 * (double)num3 + 3.0 * (double)num2);
	float num6 = num3 - 2.0f * num2 + num1;
	float num7 = num3 - num2;

	return (float)((double)value1 * (double)num4 + (double)value2 * (double)num5 + (double)tangent1 * (double)num6 + (double)tangent2 * (double)num7);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 각이 360도를 넘어섰을때 각을 뒤집어줌(? 표현 진짜 거시기허네)
///@param angle : 각
///@return 결과
//////////////////////////////////////////////////////////////////////////
float MathHelper::WrapAngle( float angle )
{
	angle = (float)fmod((double) angle, 6.28318548202515);
	
	if ((double)angle <= -3.14159274101257)
		angle += 6.283185f;
	else if ((double)angle > 3.14159274101257)
		angle -= 6.283185f;
	
	return angle;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief y=0인 수직평면으로부터 value.Y에 대한 각도를 계산한다(아따, 요것도 표현이 쪼까 거시기허요잉)
///@param value : y축 값을 구할 벡터
//////////////////////////////////////////////////////////////////////////
float MathHelper::AngleOfInclineY( Vector3 value )
{
	if(value == Vector3::Up)
		return 90.0f;

	return ToDegrees((float)acos(Vector3::Dot(value, Vector3(value.X, 0, value.Z))));
}<file_sep>#pragma once
#include "GameModel.h"
#include "AnimationClip.h"

class GameAnimationModel : public GameModel
{
public:
	GameAnimationModel(wstring meshFile, wstring matFile);
	virtual ~GameAnimationModel();

	UINT AddClip(wstring file);
	UINT AddClip(AnimationClip* clip);
	void RemoveClip(UINT index);
	void ClearClip();
	
	AnimationClip* GetClip(UINT index);

	bool Play(UINT index, AnimationPlayMode mode);
	bool Play(UINT index, float startTime, float blendTime, float speed, AnimationPlayMode mode);

	float GetPlayTime(wstring boneName);
	Model* GetModel() { return model; }

	virtual void Update();
	virtual void Render();

protected:
	struct AnimationBlender* GetBlenderFromBoneName(wstring name);

protected:
	vector<AnimationClip *> clips;
	vector<struct AnimationBlender *> blenders;
};<file_sep>#pragma once

#include <string>
#pragma warning( disable : 4996)

struct D3DXVECTOR3;
class Matrix;
class Quaternion;

//////////////////////////////////////////////////////////////////////////
///@brief 3D 벡터
//////////////////////////////////////////////////////////////////////////
class Vector3
{
public:
	Vector3(void);
	Vector3(float value);
	Vector3(float x, float y, float z);

	Vector3 operator -(void);

	bool operator ==(const Vector3& value2) const;
	bool operator !=(const Vector3& value2) const;

	Vector3 operator +(const Vector3& value2) const;
	Vector3 operator -(const Vector3& value2) const;
	Vector3 operator *(const Vector3& value2) const;
	Vector3 operator *(const float& scaleFactor) const;
	Vector3 operator /(const Vector3& value2) const;
	Vector3 operator /(const float& divider) const;

	void operator +=(const Vector3& value2);
	void operator -=(const Vector3& value2);
	void operator *=(const Vector3& value2);
	void operator *=(const float& scaleFactor);
	void operator /=(const Vector3& value2);
	void operator /=(const float& divider);


	//////////////////////////////////////////////////////////////////////////
	///@brief float형의 *연산 처리
	///@param scalefactor : 값
	///@param value2 : 벡터
	///@return 결과 벡터
	//////////////////////////////////////////////////////////////////////////
	friend Vector3 operator *(const float scaleFactor, const Vector3& value2)
	{
		return value2 * scaleFactor;
	}
	//////////////////////////////////////////////////////////////////////////


	std::string ToString();
	D3DXVECTOR3 ToD3DXVECTOR3();

	float Length();
	float LengthSquared();

	void Normalize();

	static float Distance(Vector3 value1, Vector3 value2);
	static float DistanceSquared(Vector3 value1, Vector3 value2);

	static float Dot(Vector3 value1, Vector3 value2);
	static Vector3 Normalize(Vector3 value);

	static Vector3 Cross(Vector3 vector1, Vector3 vector2);
	static Vector3 Reflect(Vector3 vector, Vector3 normal);

	static Vector3 Min(Vector3 value1, Vector3 value2);
	static Vector3 Max(Vector3 value1, Vector3 value2);
	static Vector3 Clamp(Vector3 value1, Vector3 min, Vector3 max);

	static Vector3 Lerp(Vector3 value1, Vector3 value2, float amount);
	static Vector3 SmoothStep(Vector3 value1, Vector3 value2, float amount);
	static Vector3 CatmullRom(Vector3 value1, Vector3 value2, Vector3 value3, Vector3 value4, float amount);
	static Vector3 Hermite(Vector3 value1, Vector3 tangent1, Vector3 value2, Vector3 tangent2, float amount);

	static Vector3 Transform(Vector3 position, Matrix matrix);
	static Vector3 Transform(Vector3 value, Quaternion rotation);
	static Vector3 TransformNormal(Vector3 normal, Matrix matrix);
	static Vector3 TransformCoord(Vector3 position, Matrix matrix);

public:
	const static Vector3 Zero;///< 0.0f, 0.0f, 0.0f
	const static Vector3 One;///< 1.0f, 1.0f, 1.0f
	
	const static Vector3 UnitX;///< 1.0f, 0.0f, 0.0f
	const static Vector3 UnitY;///< 0.0f, 1.0f, 0.0f
	const static Vector3 UnitZ;///< 0.0f, 0.0f, 1.0f

	const static Vector3 Up;///< 0.0f, 1.0f, 0.0f
	const static Vector3 Down;///< 0.0f, -1.0f, 0.0f
	const static Vector3 Right;///< 1.0f, 0.0f, 0.0f
	const static Vector3 Left;///< -1.0f, 0.0f, 0.0f
	const static Vector3 Forward;///< 0.0f, 0.0f, -1.0f
	const static Vector3 Backward;///< 0.0f, 0.0f, 1.0f

	float X;///< X
	float Y;///< Y
	float Z;///< Z
};<file_sep>#pragma once
#include "../Objects/GameAnimationModel.h"
class ToolsModel: public GameAnimationModel
{
public:
	enum class LowerAction;
	enum class UpperAction;

public:
	ToolsModel(wstring animPath, wstring matFile, wstring meshFile);
	~ToolsModel();

	void Update();
	void Render();

private:
	

	

	
};<file_sep>[Window][Debug##Default]
Pos=106,231
Size=400,400
Collapsed=0

[Window][System Info]
Pos=580,23
Size=336,155
Collapsed=0

[Window][Environment]
Pos=15,32
Size=538,336
Collapsed=0

[Window][Landscape]
Pos=142,156
Size=487,222
Collapsed=0

[Window][Model Info]
Pos=21,27
Size=383,698
Collapsed=0

[Window][ImGui Demo]
Pos=60,60
Size=550,680
Collapsed=0

<file_sep>#include "stdafx.h"
#include "ToolsModel.h"

ToolsModel::ToolsModel(wstring animPath, wstring matFile, wstring meshFile)
	: GameAnimationModel(matFile, meshFile)
{

	
}

ToolsModel::~ToolsModel()
{
}

void ToolsModel::Update()
{
	

	GameAnimationModel::Update();
}

void ToolsModel::Render()
{
	GameAnimationModel::Render();
}

<file_sep>#pragma once

#include <string>
#pragma warning( disable : 4996)

struct D3DXQUATERNION;
class Vector3;
class Matrix;

//////////////////////////////////////////////////////////////////////////
///@brief 사원수
//////////////////////////////////////////////////////////////////////////
class Quaternion
{
public:
	Quaternion(void);
	Quaternion(float x, float y, float z, float w);
	Quaternion(Vector3 vectorPart, float scalarPart);

	Quaternion operator -(void);

	bool operator ==(const Quaternion& quaternion2) const;
	bool operator !=(const Quaternion& quaternion2) const;

	Quaternion operator +(const Quaternion& quaternion2) const;
	Quaternion operator -(const Quaternion& quaternion2) const;
	Quaternion operator *(const Quaternion& quaternion2) const;
	Quaternion operator *(const float& scaleFactor) const;
	Quaternion operator /(const Quaternion& quaternion2) const;

	void operator +=(const Quaternion& quaternion2);
	void operator -=(const Quaternion& quaternion2);
	void operator *=(const Quaternion& quaternion2);
	void operator *=(const float& scaleFactor);
	void operator /=(const Quaternion& quaternion2);


	//////////////////////////////////////////////////////////////////////////
	///@brief float형의 *연산 처리
	///@param scalefactor : 값
	///@param value2 : 벡터
	///@return 결과 벡터
	//////////////////////////////////////////////////////////////////////////
	friend Quaternion operator *(const float scaleFactor, const Quaternion& value2)
	{
		return value2 * scaleFactor;
	}
	//////////////////////////////////////////////////////////////////////////


	std::string ToString();
	D3DXQUATERNION ToD3DXQUATERNION();

	float Length();
	float LengthSquared();

	void Normalize();
	static Quaternion Normalize(Quaternion quaternion);

	void Conjugate();
	static Quaternion Conjugate(Quaternion value);
	static Quaternion Inverse(Quaternion quaternion);

	static Quaternion CreateFromAxisAngle(Vector3 axis, float angle);
	static Quaternion CreateFromYawPitchRoll(float yaw, float pitch, float roll);
	static Quaternion CreateFromRotationMatrix(Matrix matrix);

	static float Dot(Quaternion quaternion1, Quaternion quaternion2);

	static Quaternion Slerp(Quaternion quaternion1, Quaternion quaternion2, float amount);
	static Quaternion Lerp(Quaternion quaternion1, Quaternion quaternion2, float amount);

	static Quaternion Concatenate(Quaternion value1, Quaternion value2);

public:
	const static Quaternion Identity;///< 0.0f, 0.0f, 0.0f, 1.0f

	float X;///< X
	float Y;///< Y
	float Z;///< Z
	float W;///< W
};<file_sep>#pragma once
#include "GameUnit.h"

class GamePlayer : public GameUnit
{
public:
	enum class LowerAction;
	enum class UpperAction;

public:
	GamePlayer(wstring animPath, wstring matFile, wstring meshFile);
	~GamePlayer();

	void Update();
	void Render();

private:
	void HandleInput();

	void LoadAnimation(wstring path);

	void PlayLowerAction(LowerAction action);
	void PlayLowerAction(LowerAction action, float startTime);

	void PlayUpperAction(UpperAction action);
	void PlayUpperAction(UpperAction action, float startTime);

	void ActionMovement(D3DXVECTOR3 direction);

private:
	struct GamePlayerSpec* specData;
	struct GamePlayerInput* input;

	bool bRunning;

	D3DXVECTOR3 moveDirection;
	float moveElapsedTime;
	
	float actionElapsedTime;

	float rootRotationAngle;
	float rootElapsedAngle;

	bool bActiveBooster;
	

	float runDurationTime;
	float walkDurationTime;
	float boosterFinishDurationTime;
	float boosterBreakDurationTime;
	float weaponChangeDurationTime;

private:
	enum class DebugMode
	{
		None = 0, NeverDie, Superman, God,
	};
	DebugMode debugMode;


	enum class LowerAction
	{
		Unknown = 0,
		Idle, Run, Damage, Walk, BackWalk, LeftTurn, RightTurn,
		ForwardDead, BackwardDead, LeftDead, RightDead,
		BoosterPrepare, BoosterActive, BoosterFinish, BoosterBreak,
		BoosterLeftTurn, BoosterRightTurn,
		Count,
	};

	enum class UpperAction
	{
		Unknown = 0,
		Idle, Run, Damage, WeaponChange,
		ForwardNonFire, LeftNonFire, RightNonFire,
		ForwardMachineGunFire, LeftMachineGunFire, RightMachineGunFire, ReloadMachineGun,
		ForwardShotgunFire, LeftShotgunFire, RightShotgunFire, ReloadShotgun,
		ForwardHandgunFire, LeftHandgunFire, RightHandgunFire, ReloadHandgun,
		ForwardDead, BackwardDead, LeftDead, RightDead,
		BoosterPrepare, BoosterActive, BoosterFinish, BoosterBreak,
		BoosterLeftTurn, BoosterRightTurn,
		Count,
	};

private:
	LowerAction currentLowerAction;
	UpperAction currentUpperAction;

	LowerAction prepareLowerAction;
	UpperAction prepareUpperAction;

	bool bOverwriteLowerAction;
	bool bOverwriteUpperAction;

	vector<UINT> indexLowerAnimations;
	vector<UINT> indexUpperAnimations;
};<file_sep>#pragma once

#include <string>
#pragma warning( disable : 4996)

struct D3DXVECTOR4;
class Vector2;
class Vector3;
class Matrix;
class Quaternion;

//////////////////////////////////////////////////////////////////////////
///@brief 4D 벡터
//////////////////////////////////////////////////////////////////////////
class Vector4
{
public:
	Vector4(void);
	Vector4(float x, float y, float z, float w);
	Vector4(Vector2 value, float z, float w);
	Vector4(Vector3 value, float w);
	Vector4(float value);

	Vector4 operator -(void);

	bool operator ==(const Vector4& value2) const;
	bool operator !=(const Vector4& value2) const;

	Vector4 operator +(const Vector4& value2) const;
	Vector4 operator -(const Vector4& value2) const;
	Vector4 operator *(const Vector4& value2) const;
	Vector4 operator *(const float& scaleFactor) const;
	Vector4 operator /(const Vector4& value2) const;
	Vector4 operator /(const float& divider) const;

	void operator +=(const Vector4& value2);
	void operator -=(const Vector4& value2);
	void operator *=(const Vector4& value2);
	void operator *=(const float& scaleFactor);
	void operator /=(const Vector4& value2);
	void operator /=(const float& divider);


	//////////////////////////////////////////////////////////////////////////
	///@brief float형의 *연산 처리
	///@param scalefactor : 값
	///@param value2 : 벡터
	///@return 결과 벡터
	//////////////////////////////////////////////////////////////////////////
	friend Vector4 operator *(const float scaleFactor, const Vector4& value2)
	{
		return value2 * scaleFactor;
	}
	//////////////////////////////////////////////////////////////////////////


	std::string ToString();
	D3DXVECTOR4 ToD3DXVECTOR4();

	float Length();
	float LengthSquared();

	void Normalize();

	static float Distance(Vector4 value1, Vector4 value2);
	static float DistanceSquared(Vector4 value1, Vector4 value2);

	static float Dot(Vector4 value1, Vector4 value2);
	static Vector4 Normalize(Vector4 value);

	static Vector4 Min(Vector4 value1, Vector4 value2);
	static Vector4 Max(Vector4 value1, Vector4 value2);
	static Vector4 Clamp(Vector4 value1, Vector4 min, Vector4 max);

	static Vector4 Lerp(Vector4 value1, Vector4 value2, float amount);
	static Vector4 SmoothStep(Vector4 value1, Vector4 value2, float amount);
	static Vector4 CatmullRom(Vector4 value1, Vector4 value2, Vector4 value3, Vector4 value4, float amount);
	static Vector4 Hermite(Vector4 value1, Vector4 tangent1, Vector4 value2, Vector4 tangent2, float amount);

	static Vector4 Transform(Vector2 position, Matrix matrix);
	static Vector4 Transform(Vector3 position, Matrix matrix);
	static Vector4 Transform(Vector4 position, Matrix matrix);
	
	static Vector4 Transform(Vector2 value, Quaternion rotation);
	static Vector4 Transform(Vector3 value, Quaternion rotation);
	static Vector4 Transform(Vector4 value, Quaternion rotation);

public:
	const static Vector4 Zero;///< 0.0f, 0.0f, 0.0f, 0.0f
	const static Vector4 One;///< 1.0f, 1.0f, 1.0f, 1.0f

	const static Vector4 UnitX;///< 1.0f, 0.0f, 0.0f, 0.0f
	const static Vector4 UnitY;///< 0.0f, 1.0f, 0.0f, 0.0f
	const static Vector4 UnitZ;///< 0.0f, 0.0f, 1.0f, 0.0f
	const static Vector4 UnitW;///< 0.0f, 0.0f, 1.0f, 1.0f

	float X;///< X
	float Y;///< Y
	float Z;///< Z
	float W;///< W
};<file_sep>#pragma once
#include "GameModel.h"

class GameSkyBox : public GameModel
{
public:
	GameSkyBox(wstring matFile, wstring meshFile);
	~GameSkyBox();
};<file_sep>
#pragma once
namespace Gizmo
{
	class GizmoComponent;
}
class ModelTool : public Execute
{
public:
	ModelTool(ExecuteValues* values);
	~ModelTool();

	void Update();

	void PreRender() {}
	void Render();
	void PostRender();

	void ResizeScreen() {}


private:
	void CreateModelTrees(class ModelBone* bone);
	void ControlAnimPlayer();
	D3DXMATRIX reculsiveBone_Transform(int index);

	void ExportModel();
private:
	int currentSelectBone;
	D3DXMATRIX targetMat;
	
	class ToolsModel* player;
	class Exporter* exporter;
	Gizmo::GizmoComponent* component;
};<file_sep>#pragma once
#include "stdafx.h"

enum class UnitClassId
{
	Unknown = 0,
	LightMech, HeavyMech, Tank, Boss,
	Count,
};

enum class UnitTypeId
{
	Unknown = 0,

	//Player
	Grund, Kiev, Mark, Yager,

	//Enemy
	Cameleer, Maoming, Duskmas, Hammer, Tiger, PhantomBoss,

	Count,
};

struct GameDataSpec
{
	wstring file;
};

struct GamePlayerSpec : public GameDataSpec
{
	UnitTypeId Type = UnitTypeId::Grund;
	UnitClassId Class = UnitClassId::LightMech;

	UINT Life = 3500;

	float MechRadius = 2.0f;

	float RunSpeed = 7.0f;
	float WalkSpeed = 5.0f;
	float WalkBackwardSpeed = 4.0f;
	float TurnAngle = 45.0f;
	float CriticalDamageTime = 1.0f;
	float BoosterSpeed = 32.0f;
	float BoosterActiveTime = 1.5f;
	float BoosterPrepareTime = 0.5f;
	float BoosterCoolTime = 8.0f;
	float BoosterTurnAngle = 70.0f;

	wstring MaterialFile = L"";
	wstring MeshFile = L"";
	wstring AnimationFolder = L"";
	wstring DefaultWeaponFile = L"";

	D3DXVECTOR3 CameraTargetOffset = D3DXVECTOR3(0, 2, 0);
	D3DXVECTOR3 CameraPositionOffset = D3DXVECTOR3(0, 0, -5);
};

<file_sep>#pragma once

class ModelAnimPlayer
{
public:
	enum class Mode
	{
		Play = 0, Pause, Stop,
	};

	ModelAnimPlayer(class Model* model);
	~ModelAnimPlayer();

	void SetMode(Mode value) { mode = value; }
	Mode GetMode() { return mode; }

	void Update();
	void Render();

private:
	void UpdateTime();
	void UpdateBone();

private:
	Shader* shader;

	class Model* model;
	class ModelAnimClip* currentClip;


	Mode mode;
	bool bUseSlerp;

	int currentKeyframe;
	int nextKeyframe;

	float frameTime; //현재 프레임으로부터 경과시간
	float frameFactor; //현재 프레임과 다음 프레임 사이의 보간값
	
	vector<D3DXMATRIX> boneAnimation; //본이 애니메이션 계산된 행렬
	vector<D3DXMATRIX> renderTransform; //스키닝이 계산된 렌더용 행렬
};<file_sep>#pragma once

#include <string>
#pragma warning( disable : 4996)

#include "Vector3.h"

enum PlaneIntersectionType;

struct D3DXPLANE;
class Vector4;
class Matrix;
class Quaternion;

class BoundingBox;
class BoundingFrustum;
class BoundingSphere;

//////////////////////////////////////////////////////////////////////////
///@brief 평면
//////////////////////////////////////////////////////////////////////////
class Plane
{
public:
	Plane(void);
	Plane(float a, float b, float c, float d);
	Plane(Vector3 normal, float d);
	Plane(Vector4 value);
	Plane(Vector3 point1, Vector3 point2, Vector3 point3);

	bool operator ==(const Plane& value) const;
	bool operator !=(const Plane& value) const;

	std::string ToString();
	D3DXPLANE ToD3DXPLANE();

	void Normalize();
	float Dot(Vector4 value);
	float DotCoordinate(Vector3 value);
	float DotNormal(Vector3 value);

	static Plane Normalize(Plane value);
	static Plane Transform(Plane plane, Matrix matrix);
	static Plane Transform(Plane plane, Quaternion rotation);

	PlaneIntersectionType Intersects(BoundingBox box);
	PlaneIntersectionType Intersects(BoundingFrustum frustum);
	PlaneIntersectionType Intersects(BoundingSphere sphere);

public:
	Vector3 Normal;///< 노멀 벡터
	float D;///< 원점으로부터의 거리
};<file_sep>#pragma once

#include "../Core/Vector3.h"

enum PlaneIntersectionType;
enum ContainmentType;

class BoundingSphere;
class BoundingFrustum;
class Ray;
class Plane;

//////////////////////////////////////////////////////////////////////////
///@brief 충돌 박스
//////////////////////////////////////////////////////////////////////////
class BoundingBox
{
public:
	BoundingBox(void);
	BoundingBox(Vector3 min, Vector3 max);

	bool operator ==(const BoundingBox& value) const;
	bool operator !=(const BoundingBox& value) const;

	void GetCorners(Vector3* pCorner);
	std::string ToString();

	Vector3 SupportMapping(Vector3 v); 

	static BoundingBox CreateMerged(BoundingBox original, BoundingBox additional);
	static BoundingBox CreateFromSphere(BoundingSphere sphere);

	bool Intersects(BoundingBox box);
	bool Intersects(BoundingFrustum frustum);
	PlaneIntersectionType Intersects(Plane plane);
	bool Intersects(Ray ray, float* result);
	bool Intersects(BoundingSphere sphere);

	ContainmentType Contains(BoundingBox box);
	ContainmentType Contains(BoundingFrustum frustum);
	ContainmentType Contains(Vector3 point);
	ContainmentType Contains(BoundingSphere sphere);

public:
	const static int CornerCount;///< 모서리 갯수

	Vector3 Min;///< 최소위치
	Vector3 Max;///< 최대위치
};<file_sep>#include "Ray.h"

#include "BoundingBox.h"
#include "BoundingFrustum.h"
#include "BoundingSphere.h"

#include "../Core/Plane.h"
#include "../Core/MathHelper.h"

//////////////////////////////////////////////////////////////////////////
///@brief 생성자
//////////////////////////////////////////////////////////////////////////
Ray::Ray( void )
{
	this->Position = Vector3::Zero;
	this->Direction = Vector3::Zero;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
///@param Position : 위치
///@param Direction : 방향
//////////////////////////////////////////////////////////////////////////
Ray::Ray( Vector3 position, Vector3 direction )
{
	this->Position = position;
	this->Direction = direction;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief ==
///@param value : 레이
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool Ray::operator==( const Ray& value ) const
{
	if((double)Position.X == (double)value.Position.X && (double)Position.Y == (double)value.Position.Y && ((double)Position.Z == (double)value.Position.Z && (double)Direction.X == (double)value.Direction.X)&& (double)Direction.Y == (double)value.Direction.Y)
		return (double)Direction.Z == (double)value.Direction.Z;
	else
		return false;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief !=
///@param value : 레이
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool Ray::operator!=( const Ray& value ) const
{
	if((double)Position.X == (double)value.Position.X && (double)Position.Y == (double)value.Position.Y && ((double)Position.Z == (double)value.Position.Z && (double)Direction.X == (double)value.Direction.X)&& (double)Direction.Y == (double)value.Direction.Y)
		return (double)Direction.Z != (double)value.Direction.Z;
	else
		return true;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 문자열로 변환
///@param 문자열
//////////////////////////////////////////////////////////////////////////
std::string Ray::ToString()
{
	std::string temp;

	temp += "{{Position:" + Position.ToString() + "}, ";
	temp += "{Direction:" + Direction.ToString() + "}}";

	return temp;
}

//////////////////////////////////////////////////////////////////////////
bool Ray::Intersects(Plane & plane, float& value)
{
	float x = plane.Normal.X * this->Direction.X + plane.Normal.Y * this->Direction.Y + plane.Normal.Z * this->Direction.Z;
	if (MathHelper::Abs(x) < 1E-05f)
	{
		value = 0.0f;
		return false;
	}
	float single = plane.Normal.X * this->Position.X + plane.Normal.Y * this->Position.Y + plane.Normal.Z * this->Position.Z;
	float d = (-plane.D - single) / x;
	if (d < 0.0f)
	{
		if (d < -1E-05f)
		{
			value = 0.0f;
			return false;
		}
		d = 0.0f;
	}
	value = d;
	return true;
}

//////////////////////////////////////////////////////////////////////////
bool Ray::Intersects(BoundingSphere& sphere, float & value)
{
	float x = sphere.Center.X - this->Position.X;
	float y = sphere.Center.Y - this->Position.Y;
	float z = sphere.Center.Z - this->Position.Z;
	float single = x * x + y * y + z * z;
	float radius = sphere.Radius * sphere.Radius;
	if (single <= radius)
	{
		value = 0;
		return true;
	}
	float x1 = x * this->Direction.X + y * this->Direction.Y + z * this->Direction.Z;
	if (x1 < 0.0f)
	{
		value = 0;
		return false;
	}
	float single1 = single - x1 * x1;
	if (single1 > radius)
	{
		value = 0;
		return false;
	}
	float single2 = (float)sqrt((double)(radius - single1));
	value = x1 - single2;
	return true;
}
//////////////////////////////////////////////////////////////////////////<file_sep>#pragma once

#include "../Core/Vector3.h"

//////////////////////////////////////////////////////////////////////////
///@brief GJK 충돌검출
//////////////////////////////////////////////////////////////////////////
class Gjk
{
public:
	Gjk(void);

	bool FullSimplex() const;
	float MaxLengthSquared() const;
	Vector3 ClosestPoint() const;

	void Reset();

	bool AddSupportPoint(Vector3 newPoint);

private:
	void UpdateDeterminant(int index);
	bool UpdateSimplex(int newIndex);
	Vector3 ComputeClosestPoint();
	bool IsSatisfiesRule(int xBits, int yBits);

	static float Dot(Vector3 a, Vector3 b);

private:
	const static int BitsToIndices[16];

	Vector3 closestPoint; ///< 가까운 위치 벡터
	
	Vector3 y[4];///< y축 벡터
	float yLengthSq[4];///< y축 방향 크기
	
	Vector3 edges[4][4];///< 모서리 벡터
	float edgeLengthSq[4][4];///< 모서리 크기
	
	float det[16][4];///< Determinant
	
	int simplexBits;///< 심플렉스 비트(max:15)
	float maxLengthSq;///< 제곱으로 계산한 크기 중 가장 큰 값
};<file_sep>#include "Matrix.h"

#include <assert.h>
#include <d3dx9math.h>
#include "Vector3.h"
#include "Quaternion.h"
#include "Plane.h"

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

const Matrix Matrix::Identity = Matrix(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);

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

//////////////////////////////////////////////////////////////////////////
///@brief 생성자
//////////////////////////////////////////////////////////////////////////
Matrix::Matrix( void )
{
	this->M11 = 0.0f; this->M12 = 0.0f; this->M13 = 0.0f; this->M14 = 0.0f;
	this->M21 = 0.0f; this->M22 = 0.0f; this->M23 = 0.0f; this->M24 = 0.0f;
	this->M31 = 0.0f; this->M32 = 0.0f; this->M33 = 0.0f; this->M34 = 0.0f;
	this->M41 = 0.0f; this->M42 = 0.0f; this->M43 = 0.0f; this->M44 = 0.0f;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
///@param m11 : M11
///@param m12 : M12
///@param m13 : M13
///@param m14 : M14
///@param m21 : M21
///@param m22 : M22
///@param m23 : M23
///@param m24 : M24
///@param m31 : M31
///@param m32 : M32
///@param m33 : M33
///@param m34 : M34
///@param m41 : M41
///@param m42 : M42
///@param m43 : M43
///@param m44 : M44
//////////////////////////////////////////////////////////////////////////
Matrix::Matrix( float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24, float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44 )
{
	this->M11 = m11; this->M12 = m12; this->M13 = m13; this->M14 = m14;
	this->M21 = m21; this->M22 = m22; this->M23 = m23; this->M24 = m24;
	this->M31 = m31; this->M32 = m32; this->M33 = m33; this->M34 = m34;
	this->M41 = m41; this->M42 = m42; this->M43 = m43; this->M44 = m44;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 업 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Matrix::Up()
{
	Vector3 vector3;
	vector3.X = this->M21; vector3.Y = this->M22; vector3.Z = this->M23;

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 업 벡터
///@param value : 벡터
//////////////////////////////////////////////////////////////////////////
void Matrix::Up( Vector3 value )
{
	this->M21 = value.X; this->M22 = value.Y; this->M23 = value.Z;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 다운 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Matrix::Down()
{
	Vector3 vector3;
	vector3.X = -this->M21; vector3.Y = -this->M22; vector3.Z = -this->M23;

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 다운 벡터
///@param value : 벡터
//////////////////////////////////////////////////////////////////////////
void Matrix::Down( Vector3 value )
{
	this->M21 = -value.X; this->M22 = -value.Y; this->M23 = -value.Z;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 라이트 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Matrix::Right()
{
	Vector3 vector3;
	vector3.X = this->M11; vector3.Y = this->M12; vector3.Z = this->M13;

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 다운 벡터
///@param value : 벡터
//////////////////////////////////////////////////////////////////////////
void Matrix::Right( Vector3 value )
{
	this->M11 = value.X; this->M12 = value.Y; this->M13 = value.Z;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 레프트 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Matrix::Left()
{
	Vector3 vector3;
	vector3.X = -this->M11; vector3.Y = -this->M12; vector3.Z = -this->M13;

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 레프트 벡터
///@param value : 벡터
//////////////////////////////////////////////////////////////////////////
void Matrix::Left( Vector3 value )
{
	this->M11 = -value.X; this->M12 = -value.Y; this->M13 = -value.Z;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 포워드 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Matrix::Forward()
{
	Vector3 vector3;
	vector3.X = -this->M31; vector3.Y = -this->M32; vector3.Z = -this->M33;

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 포워드 벡터
///@param value : 벡터
//////////////////////////////////////////////////////////////////////////
void Matrix::Forward( Vector3 value )
{
	this->M31 = -value.X; this->M32 = -value.Y; this->M33 = -value.Z;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 백워드 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Matrix::Backward()
{
	Vector3 vector3;
	vector3.X = this->M31; vector3.Y = this->M32; vector3.Z = this->M33;

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 백워드 벡터
///@param value : 벡터
//////////////////////////////////////////////////////////////////////////
void Matrix::Backward( Vector3 value )
{
	this->M31 = value.X; this->M32 = value.Y; this->M33 = value.Z;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 이동 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Matrix::Translate()
{
	Vector3 vector3;
	vector3.X = this->M41; vector3.Y = this->M42; vector3.Z = this->M43;

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 이동 벡터
///@param value : 벡터
//////////////////////////////////////////////////////////////////////////
void Matrix::Translate( Vector3 value )
{
	this->M41 = value.X; this->M42 = value.Y; this->M43 = value.Z;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief -
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::operator-()
{
	Matrix matrix;
	matrix.M11 = -M11; matrix.M12 = -M12; matrix.M13 = -M13; matrix.M14 = -M14;
	matrix.M21 = -M21; matrix.M22 = -M22; matrix.M23 = -M23; matrix.M24 = -M24;
	matrix.M31 = -M31; matrix.M32 = -M32; matrix.M33 = -M33; matrix.M34 = -M34;
	matrix.M41 = -M41; matrix.M42 = -M42; matrix.M43 = -M43; matrix.M44 = -M44;

	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief ==
///@param matrix2 : 매트릭스
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool Matrix::operator==( const Matrix& matrix2 ) const
{
	if ((double)this->M11 == (double)matrix2.M11 && (double)this->M22 == (double)matrix2.M22 && ((double)this->M33 == (double)matrix2.M33 && (double)this->M44 == (double)matrix2.M44)&& ((double)this->M12 == (double)matrix2.M12 && (double)this->M13 == (double)matrix2.M13 && ((double)this->M14 == (double)matrix2.M14 && (double)this->M21 == (double)matrix2.M21))&& ((double)this->M23 == (double)matrix2.M23 && (double)this->M24 == (double)matrix2.M24 && ((double)this->M31 == (double)matrix2.M31 && (double)this->M32 == (double)matrix2.M32)&& ((double)this->M34 == (double)matrix2.M34 && (double)this->M41 == (double)matrix2.M41 && (double)this->M42 == (double)matrix2.M42)))
		return (double)this->M43 == (double)matrix2.M43;
	else
		return false;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief !=
///@param matrix2 : 매트릭스
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool Matrix::operator!=( const Matrix& matrix2 ) const
{
	if ((double)this->M11 == (double)matrix2.M11 && (double)this->M12 == (double)matrix2.M12 && ((double)this->M13 == (double)matrix2.M13 && (double)this->M14 == (double)matrix2.M14)&& ((double)this->M21 == (double)matrix2.M21 && (double)this->M22 == (double)matrix2.M22 && ((double)this->M23 == (double)matrix2.M23 && (double)this->M24 == (double)matrix2.M24))&& ((double)this->M31 == (double)matrix2.M31 && (double)this->M32 == (double)matrix2.M32 && ((double)this->M33 == (double)matrix2.M33 && (double)this->M34 == (double)matrix2.M34)&& ((double)this->M41 == (double)matrix2.M41 && (double)this->M42 == (double)matrix2.M42 && (double)this->M43 == (double)matrix2.M43)))
		return (double)this->M44 != (double)matrix2.M44;
	else
		return true;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief +
///@param matrix2 : 매트릭스
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::operator+( const Matrix& matrix2 ) const
{
	Matrix matrix;
	matrix.M11 = this->M11 + matrix2.M11; matrix.M12 = this->M12 + matrix2.M12; matrix.M13 = this->M13 + matrix2.M13; matrix.M14 = this->M14 + matrix2.M14;
	matrix.M21 = this->M21 + matrix2.M21; matrix.M22 = this->M22 + matrix2.M22; matrix.M23 = this->M23 + matrix2.M23; matrix.M24 = this->M24 + matrix2.M24;
	matrix.M31 = this->M31 + matrix2.M31; matrix.M32 = this->M32 + matrix2.M32; matrix.M33 = this->M33 + matrix2.M33; matrix.M34 = this->M34 + matrix2.M34;
	matrix.M41 = this->M41 + matrix2.M41; matrix.M42 = this->M42 + matrix2.M42; matrix.M43 = this->M43 + matrix2.M43; matrix.M44 = this->M44 + matrix2.M44;

	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief -
///@param matrix2 : 매트릭스
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::operator-( const Matrix& matrix2 ) const
{
	Matrix matrix;
	matrix.M11 = this->M11 - matrix2.M11; matrix.M12 = this->M12 - matrix2.M12; matrix.M13 = this->M13 - matrix2.M13; matrix.M14 = this->M14 - matrix2.M14;
	matrix.M21 = this->M21 - matrix2.M21; matrix.M22 = this->M22 - matrix2.M22; matrix.M23 = this->M23 - matrix2.M23; matrix.M24 = this->M24 - matrix2.M24;
	matrix.M31 = this->M31 - matrix2.M31; matrix.M32 = this->M32 - matrix2.M32; matrix.M33 = this->M33 - matrix2.M33; matrix.M34 = this->M34 - matrix2.M34;
	matrix.M41 = this->M41 - matrix2.M41; matrix.M42 = this->M42 - matrix2.M42; matrix.M43 = this->M43 - matrix2.M43; matrix.M44 = this->M44 - matrix2.M44;

	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief *
///@param matrix2 : 매트릭스
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::operator*( const Matrix& matrix2 ) const
{
	Matrix matrix;
	matrix.M11 = (float)((double)this->M11 * (double)matrix2.M11 + (double)this->M12 * (double)matrix2.M21 + (double)this->M13 * (double)matrix2.M31 + (double)this->M14 * (double)matrix2.M41);
	matrix.M12 = (float)((double)this->M11 * (double)matrix2.M12 + (double)this->M12 * (double)matrix2.M22 + (double)this->M13 * (double)matrix2.M32 + (double)this->M14 * (double)matrix2.M42);
	matrix.M13 = (float)((double)this->M11 * (double)matrix2.M13 + (double)this->M12 * (double)matrix2.M23 + (double)this->M13 * (double)matrix2.M33 + (double)this->M14 * (double)matrix2.M43);
	matrix.M14 = (float)((double)this->M11 * (double)matrix2.M14 + (double)this->M12 * (double)matrix2.M24 + (double)this->M13 * (double)matrix2.M34 + (double)this->M14 * (double)matrix2.M44);
	matrix.M21 = (float)((double)this->M21 * (double)matrix2.M11 + (double)this->M22 * (double)matrix2.M21 + (double)this->M23 * (double)matrix2.M31 + (double)this->M24 * (double)matrix2.M41);
	matrix.M22 = (float)((double)this->M21 * (double)matrix2.M12 + (double)this->M22 * (double)matrix2.M22 + (double)this->M23 * (double)matrix2.M32 + (double)this->M24 * (double)matrix2.M42);
	matrix.M23 = (float)((double)this->M21 * (double)matrix2.M13 + (double)this->M22 * (double)matrix2.M23 + (double)this->M23 * (double)matrix2.M33 + (double)this->M24 * (double)matrix2.M43);
	matrix.M24 = (float)((double)this->M21 * (double)matrix2.M14 + (double)this->M22 * (double)matrix2.M24 + (double)this->M23 * (double)matrix2.M34 + (double)this->M24 * (double)matrix2.M44);
	matrix.M31 = (float)((double)this->M31 * (double)matrix2.M11 + (double)this->M32 * (double)matrix2.M21 + (double)this->M33 * (double)matrix2.M31 + (double)this->M34 * (double)matrix2.M41);
	matrix.M32 = (float)((double)this->M31 * (double)matrix2.M12 + (double)this->M32 * (double)matrix2.M22 + (double)this->M33 * (double)matrix2.M32 + (double)this->M34 * (double)matrix2.M42);
	matrix.M33 = (float)((double)this->M31 * (double)matrix2.M13 + (double)this->M32 * (double)matrix2.M23 + (double)this->M33 * (double)matrix2.M33 + (double)this->M34 * (double)matrix2.M43);
	matrix.M34 = (float)((double)this->M31 * (double)matrix2.M14 + (double)this->M32 * (double)matrix2.M24 + (double)this->M33 * (double)matrix2.M34 + (double)this->M34 * (double)matrix2.M44);
	matrix.M41 = (float)((double)this->M41 * (double)matrix2.M11 + (double)this->M42 * (double)matrix2.M21 + (double)this->M43 * (double)matrix2.M31 + (double)this->M44 * (double)matrix2.M41);
	matrix.M42 = (float)((double)this->M41 * (double)matrix2.M12 + (double)this->M42 * (double)matrix2.M22 + (double)this->M43 * (double)matrix2.M32 + (double)this->M44 * (double)matrix2.M42);
	matrix.M43 = (float)((double)this->M41 * (double)matrix2.M13 + (double)this->M42 * (double)matrix2.M23 + (double)this->M43 * (double)matrix2.M33 + (double)this->M44 * (double)matrix2.M43);
	matrix.M44 = (float)((double)this->M41 * (double)matrix2.M14 + (double)this->M42 * (double)matrix2.M24 + (double)this->M43 * (double)matrix2.M34 + (double)this->M44 * (double)matrix2.M44);

	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief *
///@param scaleFactor : 값
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::operator*( const float& scaleFactor ) const
{
	float num = scaleFactor;
	Matrix matrix1;

	matrix1.M11 = this->M11 * num; matrix1.M12 = this->M12 * num; matrix1.M13 = this->M13 * num; matrix1.M14 = this->M14 * num;
	matrix1.M21 = this->M21 * num; matrix1.M22 = this->M22 * num; matrix1.M23 = this->M23 * num; matrix1.M24 = this->M24 * num;
	matrix1.M31 = this->M31 * num; matrix1.M32 = this->M32 * num; matrix1.M33 = this->M33 * num; matrix1.M34 = this->M34 * num;
	matrix1.M41 = this->M41 * num; matrix1.M42 = this->M42 * num; matrix1.M43 = this->M43 * num; matrix1.M44 = this->M44 * num;

	return matrix1;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief /
///@param matrix2 : 매트릭스
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::operator/( const Matrix& matrix2 ) const
{
	Matrix matrix;
	matrix.M11 = this->M11 / matrix2.M11; matrix.M12 = this->M12 / matrix2.M12; matrix.M13 = this->M13 / matrix2.M13; matrix.M14 = this->M14 / matrix2.M14;
	matrix.M21 = this->M21 / matrix2.M21; matrix.M22 = this->M22 / matrix2.M22; matrix.M23 = this->M23 / matrix2.M23; matrix.M24 = this->M24 / matrix2.M24;
	matrix.M31 = this->M31 / matrix2.M31; matrix.M32 = this->M32 / matrix2.M32; matrix.M33 = this->M33 / matrix2.M33; matrix.M34 = this->M34 / matrix2.M34;
	matrix.M41 = this->M41 / matrix2.M41; matrix.M42 = this->M42 / matrix2.M42; matrix.M43 = this->M43 / matrix2.M43; matrix.M44 = this->M44 / matrix2.M44;

	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief /
///@param divider : 값
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::operator/( const float& divider ) const
{
	float num = 1.0f / divider;
	
	Matrix matrix;
	matrix.M11 = this->M11 * num; matrix.M12 = this->M12 * num; matrix.M13 = this->M13 * num; matrix.M14 = this->M14 * num;
	matrix.M21 = this->M21 * num; matrix.M22 = this->M22 * num; matrix.M23 = this->M23 * num; matrix.M24 = this->M24 * num;
	matrix.M31 = this->M31 * num; matrix.M32 = this->M32 * num; matrix.M33 = this->M33 * num; matrix.M34 = this->M34 * num;
	matrix.M41 = this->M41 * num; matrix.M42 = this->M42 * num; matrix.M43 = this->M43 * num; matrix.M44 = this->M44 * num;

	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief +=
///@param matrix2 : 매트릭스
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
void Matrix::operator+=( const Matrix& matrix2 )
{
	*this = *this + matrix2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief -=
///@param matrix2 : 매트릭스
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
void Matrix::operator-=( const Matrix& matrix2 )
{
	*this = *this - matrix2;	
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief *=
///@param matrix2 : 매트릭스
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
void Matrix::operator*=( const Matrix& matrix2 )
{
	*this = *this * matrix2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief *=
///@param scaleFactor : 값
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
void Matrix::operator*=( const float& scaleFactor )
{
	*this = *this * scaleFactor;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief /=
///@param matrix2 : 매트릭스
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
void Matrix::operator/=( const Matrix& matrix2 )
{
	*this = *this / matrix2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief /=
///@param divider : 값
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
void Matrix::operator/=( const float& divider )
{
	*this = *this / divider;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 문자열로 변환
///@return 문자열
//////////////////////////////////////////////////////////////////////////
std::string Matrix::ToString()
{
	std::string temp;
	char val[255];

	sprintf(val, "{ {M11:%#f ", M11); temp += val;
	sprintf(val, "M12:%#f ", M12); temp += val;
	sprintf(val, "M13:%#f ", M13); temp += val;
	sprintf(val, "M14:%#f} ", M14); temp += val;

	sprintf(val, "{M21:%#f ", M21); temp += val;
	sprintf(val, "M22:%#f ", M22); temp += val;
	sprintf(val, "M23:%#f ", M23); temp += val;
	sprintf(val, "M24:%#f} ", M24); temp += val;

	sprintf(val, "{321:%#f ", M31); temp += val;
	sprintf(val, "M32:%#f ", M32); temp += val;
	sprintf(val, "M33:%#f ", M33); temp += val;
	sprintf(val, "M34:%#f} ", M34); temp += val;

	sprintf(val, "{M41:%#f ", M41); temp += val;
	sprintf(val, "M42:%#f ", M42); temp += val;
	sprintf(val, "M43:%#f ", M43); temp += val;
	sprintf(val, "M44:%#f} }", M44); temp += val;

	return temp;	
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief D3DXMATRIX로 변환
///@return D3DX 매트릭스 
//////////////////////////////////////////////////////////////////////////
D3DXMATRIX Matrix::ToD3DXMATRIX()
{
	D3DXMATRIX matrix;
	matrix._11 = this->M11; matrix._12 = this->M12; matrix._13 = this->M13; matrix._14 = this->M14;
	matrix._21 = this->M21; matrix._22 = this->M22; matrix._23 = this->M23; matrix._24 = this->M24;
	matrix._31 = this->M31; matrix._32 = this->M32; matrix._33 = this->M33; matrix._34 = this->M34;
	matrix._41 = this->M41; matrix._42 = this->M42; matrix._43 = this->M43; matrix._44 = this->M44;

	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 행렬식
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
float Matrix::Determinant()
{
	float num1 = (float)((double)M33 * (double)M44 - (double)M34 * (double)M43);
	float num2 = (float)((double)M32 * (double)M44 - (double)M34 * (double)M42);
	float num3 = (float)((double)M32 * (double)M43 - (double)M33 * (double)M42);
	float num4 = (float)((double)M31 * (double)M44 - (double)M34 * (double)M41);
	float num5 = (float)((double)M31 * (double)M43 - (double)M33 * (double)M41);
	float num6 = (float)((double)M31 * (double)M42 - (double)M32 * (double)M41);

	float temp = 
		(float)((double)M11 * ((double)M22 * (double)num1 - (double)M23 * (double)num2 + (double)M24 * (double)num3) - 
				(double)M12 * ((double)M21 * (double)num1 - (double)M23 * (double)num4 + (double)M24 * (double)num5) + 
				(double)M13 * ((double)M21 * (double)num2 - (double)M22 * (double)num4 + (double)M24 * (double)num6) - 
				(double)M14 * ((double)M21 * (double)num3 - (double)M22 * (double)num5 + (double)M23 * (double)num6));

	return temp;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 빌보드 매트릭스 생성
///@param objectPosition : 오브젝트 위치
///@param cameraPosition : 카메라 위치
///@param cameraUpVector : 카메라 업벡터
///@param cameraForwardVector : 카메라 포워드벡터
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::CreateBillboard( Vector3 objectPosition, Vector3 cameraPosition, Vector3 cameraUpVector, Vector3* cameraForwardVector/*=NULL*/ )
{
	Vector3 forwardVec;
	forwardVec.X = objectPosition.X - cameraPosition.X;
	forwardVec.Y = objectPosition.Y - cameraPosition.Y;
	forwardVec.Z = objectPosition.Z - cameraPosition.Z;

	float num = forwardVec.LengthSquared();
	if ((double) num < 9.99999974737875E-05)
		forwardVec = cameraForwardVector != NULL ? -(*cameraForwardVector) : Vector3::Forward;
	else
		forwardVec = forwardVec * (1.0f / (float)sqrt((double)num));

	Vector3 rightVec;
	rightVec = Vector3::Cross(cameraUpVector, forwardVec);
	rightVec.Normalize();

	Vector3 upVec;
	upVec = Vector3::Cross(forwardVec, rightVec);
	
	Matrix matrix;
	matrix.M11 = rightVec.X;		matrix.M12 = rightVec.Y;		matrix.M13 = rightVec.Z;		matrix.M14 = 0.0f;
	matrix.M21 = upVec.X;			matrix.M22 = upVec.Y;			matrix.M23 = upVec.Z;			matrix.M24 = 0.0f;
	matrix.M31 = forwardVec.X;		matrix.M32 = forwardVec.Y;		matrix.M33 = forwardVec.Z;		matrix.M34 = 0.0f;
	matrix.M41 = objectPosition.X;	matrix.M42 = objectPosition.Y;	matrix.M43 = objectPosition.Z;	matrix.M44 = 1.0f;

	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 이동 매트릭스 생성
///@param position : 위치
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::CreateTranslation( Vector3 position )
{
	Matrix matrix;
	matrix.M11 = 1.0f; matrix.M12 = 0.0f; matrix.M13 = 0.0f; matrix.M14 = 0.0f;
	matrix.M21 = 0.0f; matrix.M22 = 1.0f; matrix.M23 = 0.0f; matrix.M24 = 0.0f;
	matrix.M31 = 0.0f; matrix.M32 = 0.0f; matrix.M33 = 1.0f; matrix.M34 = 0.0f;
	
	matrix.M41 = position.X; 
	matrix.M42 = position.Y; 
	matrix.M43 = position.Z; 
	matrix.M44 = 1.0f;

	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 이동 매트릭스 생성
///@param xPosition : x 위치
///@param yPosition : y 위치
///@param zPosition : z 위치
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::CreateTranslation( float xPosition, float yPosition, float zPosition )
{
	Matrix matrix;
	matrix.M11 = 1.0f; matrix.M12 = 0.0f; matrix.M13 = 0.0f; matrix.M14 = 0.0f;
	matrix.M21 = 0.0f; matrix.M22 = 1.0f; matrix.M23 = 0.0f; matrix.M24 = 0.0f;
	matrix.M31 = 0.0f; matrix.M32 = 0.0f; matrix.M33 = 1.0f; matrix.M34 = 0.0f;
	
	matrix.M41 = xPosition;
	matrix.M42 = yPosition;
	matrix.M43 = zPosition;
	matrix.M44 = 1.0f;
	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 크기 매트릭스 생성
///@param scales : 크기
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::CreateScale( Vector3 scales )
{	
	Matrix matrix;
	matrix.M11 = scales.X;	matrix.M12 = 0.0f;		matrix.M13 = 0.0f;		matrix.M14 = 0.0f;
	matrix.M21 = 0.0f;		matrix.M22 = scales.Y;	matrix.M23 = 0.0f;		matrix.M24 = 0.0f;
	matrix.M31 = 0.0f;		matrix.M32 = 0.0f;		matrix.M33 = scales.Z;	matrix.M34 = 0.0f;
	matrix.M41 = 0.0f;		matrix.M42 = 0.0f;		matrix.M43 = 0.0f;		matrix.M44 = 1.0f;

	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 크기 매트릭스 생성
///@param xScale : x 크기
///@param yScale : y 크기
///@param zScale : z 크기
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::CreateScale( float xScale, float yScale, float zScale )
{
	Matrix matrix;
	matrix.M11 = xScale;	matrix.M12 = 0.0f;		matrix.M13 = 0.0f;		matrix.M14 = 0.0f;
	matrix.M21 = 0.0f;		matrix.M22 = yScale;	matrix.M23 = 0.0f;		matrix.M24 = 0.0f;
	matrix.M31 = 0.0f;		matrix.M32 = 0.0f;		matrix.M33 = zScale;	matrix.M34 = 0.0f;
	matrix.M41 = 0.0f;		matrix.M42 = 0.0f;		matrix.M43 = 0.0f;		matrix.M44 = 1.0f;

	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 크기 매트릭스 생성
///@param scale : 크기값
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::CreateScale( float scale )
{
	Matrix matrix;
	matrix.M11 = scale;	matrix.M12 = 0.0f;	matrix.M13 = 0.0f;	matrix.M14 = 0.0f;
	matrix.M21 = 0.0f;	matrix.M22 = scale;	matrix.M23 = 0.0f;	matrix.M24 = 0.0f;
	matrix.M31 = 0.0f;	matrix.M32 = 0.0f;	matrix.M33 = scale;	matrix.M34 = 0.0f;
	matrix.M41 = 0.0f;	matrix.M42 = 0.0f;	matrix.M43 = 0.0f;	matrix.M44 = 1.0f;

	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief X축 회전 매트릭스 생성
///@param radians : 라디안 각도값
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::CreateRotationX( float radians )
{
	float num1 = (float)cos((double) radians);
	float num2 = (float)sin((double) radians);
	
	Matrix matrix;
	matrix.M11 = 1.0f;	matrix.M12 = 0.0f;	matrix.M13 = 0.0f;	matrix.M14 = 0.0f;
	matrix.M21 = 0.0f;	matrix.M22 = num1;	matrix.M23 = num2;	matrix.M24 = 0.0f;
	matrix.M31 = 0.0f;	matrix.M32 = -num2;	matrix.M33 = num1;	matrix.M34 = 0.0f;
	matrix.M41 = 0.0f;	matrix.M42 = 0.0f;	matrix.M43 = 0.0f;	matrix.M44 = 1.0f;
	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief Y축 회전 매트릭스 생성
///@param radians : 라디안 각도값
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::CreateRotationY( float radians )
{
	float num1 = (float)cos((double) radians);
	float num2 = (float)sin((double) radians);
	
	Matrix matrix;
	matrix.M11 = num1; matrix.M12 = 0.0f; matrix.M13 = -num2; matrix.M14 = 0.0f;
	matrix.M21 = 0.0f; matrix.M22 = 1.0f; matrix.M23 = 0.0f; matrix.M24 = 0.0f;
	matrix.M31 = num2; matrix.M32 = 0.0f; matrix.M33 = num1; matrix.M34 = 0.0f;
	matrix.M41 = 0.0f; matrix.M42 = 0.0f; matrix.M43 = 0.0f; matrix.M44 = 1.0f;

	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief Z축 회전 매트릭스 생성
///@param radians : 라디안 각도값
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::CreateRotationZ( float radians )
{
	float num1 = (float)cos((double) radians);
	float num2 = (float)sin((double) radians);
	
	Matrix matrix;
	matrix.M11 = num1; matrix.M12 = num2; matrix.M13 = 0.0f; matrix.M14 = 0.0f;
	matrix.M21 = -num2; matrix.M22 = num1; matrix.M23 = 0.0f; matrix.M24 = 0.0f;
	matrix.M31 = 0.0f; matrix.M32 = 0.0f; matrix.M33 = 1.0f; matrix.M34 = 0.0f;
	matrix.M41 = 0.0f; matrix.M42 = 0.0f; matrix.M43 = 0.0f; matrix.M44 = 1.0f;
	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 축 벡터 회전 매트릭스 생성
///@param axis : 축
///@param angle : 회전값
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::CreateFromAxisAngle( Vector3 axis, float angle )
{
	float sinValue = (float)sin((double)angle);
	float cosValue = (float)cos((double)angle);

	float xx = axis.X * axis.X;
	float yy = axis.Y * axis.Y;
	float zz = axis.Z * axis.Z;

	float xy = axis.X * axis.Y;
	float xz = axis.X * axis.Z;
	float yz = axis.Y * axis.Z;

	Matrix matrix;
	matrix.M11 = xx + cosValue * (1.0f - xx);
	matrix.M12 = (float)((double)xy - (double)cosValue * (double)xy + (double)sinValue * (double)axis.Z);
	matrix.M13 = (float)((double)xz - (double)cosValue * (double)xz - (double)sinValue * (double)axis.Y);
	matrix.M14 = 0.0f;

	matrix.M21 = (float)((double)xy - (double)cosValue * (double)xy - (double)sinValue * (double)axis.Z);
	matrix.M22 = yy + cosValue * (1.0f - yy);
	matrix.M23 = (float)((double)yz - (double)cosValue * (double)yz + (double)sinValue * (double)axis.X);
	matrix.M24 = 0.0f;

	matrix.M31 = (float)((double)xz - (double)cosValue * (double)xz + (double)sinValue * (double)axis.Y);
	matrix.M32 = (float)((double)yz - (double)cosValue * (double)yz - (double)sinValue * (double)axis.X);
	matrix.M33 = zz + cosValue * (1.0f - zz);
	matrix.M34 = 0.0f;

	matrix.M41 = 0.0f;
	matrix.M42 = 0.0f;
	matrix.M43 = 0.0f;
	matrix.M44 = 1.0f;
	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 원근투영 매트릭스 생성
///@param width : 화면넓이
///@param height : 화면높이
///@param nearPlaneDistance : 근면거리
///@param farPlaneDistance : 원면거리
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::CreatePerspective( float width, float height, float nearPlaneDistance, float farPlaneDistance )
{
	assert((double)nearPlaneDistance > 0.0);
	assert((double)farPlaneDistance > 0.0);
	assert((double)nearPlaneDistance < (double)farPlaneDistance);

	Matrix matrix;
	matrix.M11 = 2.0f * nearPlaneDistance / width;
	matrix.M12 = matrix.M13 = matrix.M14 = 0.0f;

	matrix.M22 = 2.0f * nearPlaneDistance / height;
	matrix.M21 = matrix.M23 = matrix.M24 = 0.0f;

	matrix.M33 = farPlaneDistance / (nearPlaneDistance - farPlaneDistance);
	matrix.M31 = matrix.M32 = 0.0f;
	matrix.M34 = -1.0f;

	matrix.M41 = matrix.M42 = matrix.M44 = 0.0f;
	matrix.M43 = (float)((double)nearPlaneDistance * (double)farPlaneDistance / ((double)nearPlaneDistance - (double)farPlaneDistance));

	return matrix;	
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief FOV를 기준으로 원근투영 매트릭스 생성
///@param fieldOfView : FOV
///@param aspectRatio : 화면비율
///@param nearPlaneDistance : 근면거리
///@param farPlaneDistance : 원면거리
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::CreatePerspectiveFieldOfView( float fieldOfView, float aspectRatio, float nearPlaneDistance, float farPlaneDistance )
{
	assert((double)fieldOfView > 0.0 || (double)fieldOfView < 3.14159274101257);
	assert((double)nearPlaneDistance > 0.0);
	assert((double)farPlaneDistance > 0.0);
	assert((double)nearPlaneDistance < (double)farPlaneDistance);
	
	float num1 = 1.0f / (float)tan((double)fieldOfView * 0.5);
	float num2 = num1 / aspectRatio;
	
	Matrix matrix;
	matrix.M11 = num2; 
	matrix.M12 = matrix.M13 = matrix.M14 = 0.0f;
	
	matrix.M22 = num1; 
	matrix.M21 = matrix.M23 = matrix.M24 = 0.0f;
	
	matrix.M31 = matrix.M32 = 0.0f;
	matrix.M33 = farPlaneDistance / (nearPlaneDistance - farPlaneDistance);
	matrix.M34 = -1.0f;
	
	matrix.M41 = matrix.M42 = matrix.M44 = 0.0f;
	matrix.M43 = (float)((double)nearPlaneDistance * (double)farPlaneDistance / ((double)nearPlaneDistance - (double)farPlaneDistance));
	
	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 룩앳(뷰) 매트릭스 생성
///@param cameraPosition : 카메라 위치
///@param cameraTarget : 카메라 타켓
///@param cameraUpVector : 카메라 업벡터
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::CreateLookAt( Vector3 cameraPosition, Vector3 cameraTarget, Vector3 cameraUpVector )
{
	Vector3 vector3_1 = Vector3::Normalize(cameraPosition - cameraTarget);
	Vector3 vector3_2 = Vector3::Normalize(Vector3::Cross(cameraUpVector, vector3_1));
	Vector3 vector1 = Vector3::Cross(vector3_1, vector3_2);

	Matrix matrix;
	matrix.M11 = vector3_2.X; matrix.M12 = vector1.X; matrix.M13 = vector3_1.X; matrix.M14 = 0.0f;
	matrix.M21 = vector3_2.Y; matrix.M22 = vector1.Y; matrix.M23 = vector3_1.Y; matrix.M24 = 0.0f;
	matrix.M31 = vector3_2.Z; matrix.M32 = vector1.Z; matrix.M33 = vector3_1.Z; matrix.M34 = 0.0f;
	
	matrix.M41 = -Vector3::Dot(vector3_2, cameraPosition);
	matrix.M42 = -Vector3::Dot(vector1, cameraPosition);
	matrix.M43 = -Vector3::Dot(vector3_1, cameraPosition);
	matrix.M44 = 1.0f;
	
	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 월드 매트릭스 생성
///@param position : 위치
///@param forward : 전방 방향
///@param up : 업
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::CreateWorld( Vector3 position, Vector3 forward, Vector3 up )
{
	Vector3 vector3_1 = Vector3::Normalize(-forward);
	Vector3 vector2 = Vector3::Normalize(Vector3::Cross(up, vector3_1));
	Vector3 vector3_2 = Vector3::Cross(vector3_1, vector2);

	Matrix matrix;
	matrix.M11 = vector2.X; matrix.M12 = vector2.Y; matrix.M13 = vector2.Z; matrix.M14 = 0.0f;
	matrix.M21 = vector3_2.X; matrix.M22 = vector3_2.Y; matrix.M23 = vector3_2.Z; matrix.M24 = 0.0f;
	matrix.M31 = vector3_1.X; matrix.M32 = vector3_1.Y; matrix.M33 = vector3_1.Z; matrix.M34 = 0.0f;
	matrix.M41 = position.X; matrix.M42 = position.Y; matrix.M43 = position.Z; matrix.M44 = 1.0f;
	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 쿼터니온으로부터 매트릭스 생성
///@param quaternion : 쿼터니온
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::CreateFromQuaternion( Quaternion quaternion )
{
	float xx = quaternion.X * quaternion.X;
	float yy = quaternion.Y * quaternion.Y;
	float zz = quaternion.Z * quaternion.Z;
	float xy = quaternion.X * quaternion.Y;
	float zw = quaternion.Z * quaternion.W;
	float zx = quaternion.Z * quaternion.X;
	float yw = quaternion.Y * quaternion.W;
	float yz = quaternion.Y * quaternion.Z;
	float xw = quaternion.X * quaternion.W;

	Matrix matrix;
	matrix.M11 = (float)(1.0 - 2.0 * ((double)yy + (double)zz));
	matrix.M12 = (float)(2.0 * ((double)xy + (double)zw));
	matrix.M13 = (float)(2.0 * ((double)zx - (double)yw));
	matrix.M14 = 0.0f;

	matrix.M21 = (float)(2.0 * ((double)xy - (double)zw));
	matrix.M22 = (float)(1.0 - 2.0 * ((double)zz + (double)xx));
	matrix.M23 = (float)(2.0 * ((double)yz + (double)xw));
	matrix.M24 = 0.0f;

	matrix.M31 = (float)(2.0 * ((double)zx + (double)yw));
	matrix.M32 = (float)(2.0 * ((double)yz - (double)xw));
	matrix.M33 = (float)(1.0 - 2.0 * ((double)yy + (double)xx));

	matrix.M34 = 0.0f;
	matrix.M41 = 0.0f;
	matrix.M42 = 0.0f;
	matrix.M43 = 0.0f;
	matrix.M44 = 1.0f;

	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 각 축값에 의한 회전 매트릭스 생성(쿼터니온 이용)
///@param yaw : Yaw
///@param pitch : Pitch
///@param roll : Roll
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::CreateFromYawPitchRoll( float yaw, float pitch, float roll )
{
	Quaternion result1;
	result1 = Quaternion::CreateFromYawPitchRoll(yaw, pitch, roll);

	Matrix result2;
	result2 = CreateFromQuaternion(result1);

	return result2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 그림자 매트릭스 생성
///@param lightDirection : 빛 방향 벡터
///@param plane : 면
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::CreateShadow( Vector3 lightDirection, Plane plane )
{
	Plane result = Plane::Normalize(plane);
	float length = (float)((double)result.Normal.X * (double)lightDirection.X + (double)result.Normal.Y * (double)lightDirection.Y + (double)result.Normal.Z * (double)lightDirection.Z);

	Matrix matrix;
	matrix.M11 = -result.Normal.X * lightDirection.X + length;
	matrix.M21 = -result.Normal.Y * lightDirection.X;
	matrix.M31 = -result.Normal.Z * lightDirection.X;
	matrix.M41 = -result.D * lightDirection.X;

	matrix.M12 = -result.Normal.X * lightDirection.Y;
	matrix.M22 = -result.Normal.Y * lightDirection.Y + length;
	matrix.M32 = -result.Normal.Z * lightDirection.Y;
	matrix.M42 = -result.D * lightDirection.Y;

	matrix.M13 = -result.Normal.X * lightDirection.Z;
	matrix.M23 = -result.Normal.Y * lightDirection.Z;
	matrix.M33 = -result.Normal.Z * lightDirection.Z + length;
	matrix.M43 = -result.D * lightDirection.Z;

	matrix.M14 = 0.0f;
	matrix.M24 = 0.0f;
	matrix.M34 = 0.0f;
	matrix.M44 = length;

	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 면의 반사 매트릭스 생성
///@param value : 면
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::CreateReflection( Plane value )
{
	value.Normalize();

	Matrix matrix;
	matrix.M11 = (float)((double)(-2.0f * value.Normal.X)* (double)value.Normal.X + 1.0);
	matrix.M12 = (-2.0f * value.Normal.Y) * value.Normal.X;
	matrix.M13 = (-2.0f * value.Normal.Z) * value.Normal.X;
	matrix.M14 = 0.0f;

	matrix.M21 = (-2.0f * value.Normal.X) * value.Normal.Y;
	matrix.M22 = (float)((double)(-2.0f * value.Normal.Y)* (double)value.Normal.Y + 1.0);
	matrix.M23 = (-2.0f * value.Normal.Z) * value.Normal.Y;
	matrix.M24 = 0.0f;

	matrix.M31 = (-2.0f * value.Normal.X) * value.Normal.Z;
	matrix.M32 = (-2.0f * value.Normal.Y) * value.Normal.Z;
	matrix.M33 = (float)((double)(-2.0f * value.Normal.Z)* (double)value.Normal.Z + 1.0);
	matrix.M34 = 0.0f;

	matrix.M41 = (-2.0f * value.Normal.X) * value.D;
	matrix.M42 = (-2.0f * value.Normal.Y) * value.D;
	matrix.M43 = (-2.0f * value.Normal.Z) * value.D;
	matrix.M44 = 1.0f;

	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 정사도법에 의한 행렬 생성
///@param width : 넓이
///@param height : 높이
///@param zNearPlane : z방향 근면
///@param zFarPlane : z방향 원면
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::CreateOrthographic( float width, float height, float zNearPlane, float zFarPlane )
{
	Matrix matrix;
	matrix.M11 = 2.0f / width;
	matrix.M12 = matrix.M13 = matrix.M14 = 0.0f;
	matrix.M22 = 2.0f / height;
	matrix.M21 = matrix.M23 = matrix.M24 = 0.0f;
	matrix.M33 = (float) (1.0 / ((double) zNearPlane - (double) zFarPlane));
	matrix.M31 = matrix.M32 = matrix.M34 = 0.0f;
	matrix.M41 = matrix.M42 = 0.0f;
	matrix.M43 = zNearPlane / (zNearPlane - zFarPlane);
	matrix.M44 = 1.0f;

	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 쿼터니온에 의한 매트릭스 변환
///@param value : 매트릭스
///@param rotation : 쿼터니온
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::Transform( Matrix value, Quaternion rotation )
{
	float wxx = rotation.W * (rotation.X + rotation.X);
	float wyy = rotation.W * (rotation.Y + rotation.Y);
	float wzz = rotation.W * (rotation.Z + rotation.Z);

	float xxx = rotation.X * (rotation.X + rotation.X);
	float xyy = rotation.X * (rotation.Y + rotation.Y);
	float xzz = rotation.X * (rotation.Z + rotation.Z);

	float yyy = rotation.Y * (rotation.Y + rotation.Y);
	float yzz = rotation.Y * (rotation.Z + rotation.Z);
	float zzz = rotation.Z * (rotation.Z + rotation.Z);

	float num1 = 1.0f - yyy - zzz;
	float num2 = xyy - wzz;
	float num3 = xzz + wyy;
	float num4 = xyy + wzz;

	float num5 = 1.0f - xxx - zzz;
	float num6 = yzz - wxx;
	float num7 = xzz - wyy;
	float num8 = yzz + wxx;

	float num9 = 1.0f - xxx - yyy;

	Matrix matrix;
	matrix.M11 = (float)((double)value.M11 * (double)num1 + (double)value.M12 * (double)num2 + (double)value.M13 * (double)num3);
	matrix.M12 = (float)((double)value.M11 * (double)num4 + (double)value.M12 * (double)num5 + (double)value.M13 * (double)num6);
	matrix.M13 = (float)((double)value.M11 * (double)num7 + (double)value.M12 * (double)num8 + (double)value.M13 * (double)num9);
	matrix.M14 = value.M14;

	matrix.M21 = (float)((double)value.M21 * (double)num1 + (double)value.M22 * (double)num2 + (double)value.M23 * (double)num3);
	matrix.M22 = (float)((double)value.M21 * (double)num4 + (double)value.M22 * (double)num5 + (double)value.M23 * (double)num6);
	matrix.M23 = (float)((double)value.M21 * (double)num7 + (double)value.M22 * (double)num8 + (double)value.M23 * (double)num9);
	matrix.M24 = value.M24;

	matrix.M31 = (float)((double)value.M31 * (double)num1 + (double)value.M32 * (double)num2 + (double)value.M33 * (double)num3);
	matrix.M32 = (float)((double)value.M31 * (double)num4 + (double)value.M32 * (double)num5 + (double)value.M33 * (double)num6);
	matrix.M33 = (float)((double)value.M31 * (double)num7 + (double)value.M32 * (double)num8 + (double)value.M33 * (double)num9);
	matrix.M34 = value.M34;

	matrix.M41 = (float)((double)value.M41 * (double)num1 + (double)value.M42 * (double)num2 + (double)value.M43 * (double)num3);
	matrix.M42 = (float)((double)value.M41 * (double)num4 + (double)value.M42 * (double)num5 + (double)value.M43 * (double)num6);
	matrix.M43 = (float)((double)value.M41 * (double)num7 + (double)value.M42 * (double)num8 + (double)value.M43 * (double)num9);
	matrix.M44 = value.M44;

	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 전치 매트릭스
///@param matrix : 행렬
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::Transpose( Matrix matrix )
{
	Matrix matrix1;
	matrix1.M11 = matrix.M11; matrix1.M12 = matrix.M21; matrix1.M13 = matrix.M31; matrix1.M14 = matrix.M41;
	matrix1.M21 = matrix.M12; matrix1.M22 = matrix.M22; matrix1.M23 = matrix.M32; matrix1.M24 = matrix.M42;
	matrix1.M31 = matrix.M13; matrix1.M32 = matrix.M23; matrix1.M33 = matrix.M33; matrix1.M34 = matrix.M43;
	matrix1.M41 = matrix.M14; matrix1.M42 = matrix.M24; matrix1.M43 = matrix.M34; matrix1.M44 = matrix.M44;
	
	return matrix1;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 역행렬
///@param matrix : 매트릭스
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::Invert( Matrix matrix )
{
	Matrix matrix2;
	float num5 = matrix.M11; float num4 = matrix.M12; float num3 = matrix.M13; float num2 = matrix.M14;
	float num9 = matrix.M21; float num8 = matrix.M22; float num7 = matrix.M23; float num6 = matrix.M24;
	float num17 = matrix.M31; float num16 = matrix.M32; float num15 = matrix.M33; float num14 = matrix.M34;
	float num13 = matrix.M41; float num12 = matrix.M42; float num11 = matrix.M43; float num10 = matrix.M44;

	float num23 = (num15 * num10) - (num14 * num11);
	float num22 = (num16 * num10) - (num14 * num12);
	float num21 = (num16 * num11) - (num15 * num12);
	float num20 = (num17 * num10) - (num14 * num13);
	float num19 = (num17 * num11) - (num15 * num13);
	float num18 = (num17 * num12) - (num16 * num13);
	float num39 = ((num8 * num23) - (num7 * num22)) + (num6 * num21);
	float num38 = -(((num9 * num23) - (num7 * num20)) + (num6 * num19));
	float num37 = ((num9 * num22) - (num8 * num20)) + (num6 * num18);
	float num36 = -(((num9 * num21) - (num8 * num19)) + (num7 * num18));
	float num = 1.0f / ((((num5 * num39) + (num4 * num38)) + (num3 * num37)) + (num2 * num36));

	matrix2.M11 = num39 * num;
	matrix2.M21 = num38 * num;
	matrix2.M31 = num37 * num;
	matrix2.M41 = num36 * num;

	matrix2.M12 = -(((num4 * num23) - (num3 * num22)) + (num2 * num21)) * num;
	matrix2.M22 = (((num5 * num23) - (num3 * num20)) + (num2 * num19)) * num;
	matrix2.M32 = -(((num5 * num22) - (num4 * num20)) + (num2 * num18)) * num;
	matrix2.M42 = (((num5 * num21) - (num4 * num19)) + (num3 * num18)) * num;

	float num35 = (num7 * num10) - (num6 * num11);
	float num34 = (num8 * num10) - (num6 * num12);
	float num33 = (num8 * num11) - (num7 * num12);
	float num32 = (num9 * num10) - (num6 * num13);
	float num31 = (num9 * num11) - (num7 * num13);
	float num30 = (num9 * num12) - (num8 * num13);

	matrix2.M13 = (((num4 * num35) - (num3 * num34)) + (num2 * num33)) * num;
	matrix2.M23 = -(((num5 * num35) - (num3 * num32)) + (num2 * num31)) * num;
	matrix2.M33 = (((num5 * num34) - (num4 * num32)) + (num2 * num30)) * num;
	matrix2.M43 = -(((num5 * num33) - (num4 * num31)) + (num3 * num30)) * num;

	float num29 = (num7 * num14) - (num6 * num15);
	float num28 = (num8 * num14) - (num6 * num16);
	float num27 = (num8 * num15) - (num7 * num16);
	float num26 = (num9 * num14) - (num6 * num17);
	float num25 = (num9 * num15) - (num7 * num17);
	float num24 = (num9 * num16) - (num8 * num17);

	matrix2.M14 = -(((num4 * num29) - (num3 * num28)) + (num2 * num27)) * num;
	matrix2.M24 = (((num5 * num29) - (num3 * num26)) + (num2 * num25)) * num;
	matrix2.M34 = -(((num5 * num28) - (num4 * num26)) + (num2 * num24)) * num;
	matrix2.M44 = (((num5 * num27) - (num4 * num25)) + (num3 * num24)) * num;

	return matrix2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 두 매트릭스의 선형보간
///@param matrix1 : 매트릭스1
///@param matrix2 : 매트릭스2
///@param amount : 보간 값
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix Matrix::Lerp( Matrix matrix1, Matrix matrix2, float amount )
{
	Matrix matrix;
	matrix.M11 = matrix1.M11 + (matrix2.M11 - matrix1.M11) * amount;
	matrix.M12 = matrix1.M12 + (matrix2.M12 - matrix1.M12) * amount;
	matrix.M13 = matrix1.M13 + (matrix2.M13 - matrix1.M13) * amount;
	matrix.M14 = matrix1.M14 + (matrix2.M14 - matrix1.M14) * amount;
	matrix.M21 = matrix1.M21 + (matrix2.M21 - matrix1.M21) * amount;
	matrix.M22 = matrix1.M22 + (matrix2.M22 - matrix1.M22) * amount;
	matrix.M23 = matrix1.M23 + (matrix2.M23 - matrix1.M23) * amount;
	matrix.M24 = matrix1.M24 + (matrix2.M24 - matrix1.M24) * amount;
	matrix.M31 = matrix1.M31 + (matrix2.M31 - matrix1.M31) * amount;
	matrix.M32 = matrix1.M32 + (matrix2.M32 - matrix1.M32) * amount;
	matrix.M33 = matrix1.M33 + (matrix2.M33 - matrix1.M33) * amount;
	matrix.M34 = matrix1.M34 + (matrix2.M34 - matrix1.M34) * amount;
	matrix.M41 = matrix1.M41 + (matrix2.M41 - matrix1.M41) * amount;
	matrix.M42 = matrix1.M42 + (matrix2.M42 - matrix1.M42) * amount;
	matrix.M43 = matrix1.M43 + (matrix2.M43 - matrix1.M43) * amount;
	matrix.M44 = matrix1.M44 + (matrix2.M44 - matrix1.M44) * amount;

	return matrix;
}<file_sep>#pragma once

class Vector3;

//////////////////////////////////////////////////////////////////////////
///@brief 수학관련
//////////////////////////////////////////////////////////////////////////
class MathHelper
{
public:
	MathHelper(void);	

	static double Round(double value);
	static double Round(double value, int position);

	static int Abs(int value);
	static float Abs(float value);
	static double Abs(double value);

	static float ToRadians(float degrees);
	static float ToDegrees(float radians);
	static float Distance(float value1, float value2);

	static float Min(float value1, float value2);
	static float Max(float value1, float value2);
	static float Clamp(float value, float min, float max);
	
	static float Lerp(float value1, float value2, float amount);
	static float SmoothStep(float value1, float value2, float amount);
	static float CatmullRom(float value1, float value2, float value3, float value4, float amount);
	static float Hermite(float value1, float tangent1, float value2, float tangent2, float amount);
	static float WrapAngle(float angle);

	static float AngleOfInclineY(Vector3 value);

public:
	const static float E;///< 자연로그의 밑수
	const static float Log2E;///< 자연로그의 밑수 2
	const static float Log10E;///< 자연로그의 밑수 10
	const static float Pi;///< PI
	const static float TwoPi;///< PI * 2
	const static float PiOver2;///< PI / 2
	const static float PiOver4;///< PI / 4
	const static float Epsilon;///< 0.000001f

	const static int IntMinValue;///< Int형의 최소값
	const static int IntMaxValue;///< Int형의 최대값
	const static float FloatMinValue;///< Flaot형의 최소값
	const static float FloatMaxValue;///< Float형의 최대값
};<file_sep>#include "stdafx.h"
#include "ModelAnimPlayer.h"
#include "Model.h"
#include "ModelMesh.h"
#include "ModelBone.h"
#include "ModelAnimClip.h"

ModelAnimPlayer::ModelAnimPlayer(Model * model)
	: model(model), mode(Mode::Play)
	, currentKeyframe(0), nextKeyframe(0)
	, frameTime(0), frameFactor(0)
	, bUseSlerp(true)
{
	shader = new Shader(Shaders + L"999_Animation.hlsl");

	vector<Material *>& materials = model->Materials();
	for (Material* material : materials)
		material->SetShader(shader);

	currentClip = model->Clip(0);

	boneAnimation.assign(model->BoneCount(), D3DXMATRIX());
	renderTransform.assign(model->BoneCount(), D3DXMATRIX());
}

ModelAnimPlayer::~ModelAnimPlayer()
{
	SAFE_DELETE(shader);
}

void ModelAnimPlayer::Update()
{
	if (currentClip == NULL || mode != Mode::Play)
		return;

	UpdateTime();
	UpdateBone();

	model->Buffer()->SetBones(&renderTransform[0], renderTransform.size());
}

void ModelAnimPlayer::UpdateTime()
{
	frameTime += Time::Delta();

	float invFrameRate = 1.0f / currentClip->FrameRate();
	while (frameTime > invFrameRate)
	{
		int keyframeCount = currentClip->TotalFrame();

		currentKeyframe = (currentKeyframe + 1) % keyframeCount;
		nextKeyframe = (currentKeyframe + 1) % keyframeCount;

		frameTime -= invFrameRate;
	}

	frameFactor = frameTime / invFrameRate;
}

void ModelAnimPlayer::UpdateBone()
{
	for (size_t i = 0; i < model->BoneCount(); i++)
	{
		ModelBone* bone = model->Bone(i);

		D3DXMATRIX matAnimation;
		D3DXMATRIX matParentAnimation;

		D3DXMATRIX matInvBindPose = bone->AbsoluteTransform();
		D3DXMatrixInverse(&matInvBindPose, NULL, &matInvBindPose);

		ModelKeyframe* frame = currentClip->Keyframe(bone->Name());
		if (frame == NULL) continue;

		if (bUseSlerp == true)
		{
			D3DXMATRIX S, R, T;

			ModelKeyframeData current = frame->Datas[currentKeyframe];
			ModelKeyframeData next = frame->Datas[nextKeyframe];


			D3DXVECTOR3 s1 = current.Scale;
			D3DXVECTOR3 s2 = next.Scale;

			D3DXVECTOR3 s;
			D3DXVec3Lerp(&s, &s1, &s2, frameFactor);
			D3DXMatrixScaling(&S, s.x, s.y, s.z);


			D3DXQUATERNION q1 = current.Rotation;
			D3DXQUATERNION q2 = next.Rotation;

			D3DXQUATERNION q;
			D3DXQuaternionSlerp(&q, &q1, &q2, frameFactor);
			D3DXMatrixRotationQuaternion(&R, &q);


			D3DXVECTOR3 t1 = current.Translation;
			D3DXVECTOR3 t2 = next.Translation;

			D3DXVECTOR3 t;
			D3DXVec3Lerp(&t, &t1, &t2, frameFactor);
			D3DXMatrixTranslation(&T, t.x, t.y, t.z);

			matAnimation = S * R * T;
		}
		else
		{
			matAnimation = frame->Datas[currentKeyframe].Transform;
		}

		int parentIndex = bone->ParentIndex();
		if (parentIndex < 0)
			D3DXMatrixIdentity(&matParentAnimation);
		else
			matParentAnimation = boneAnimation[parentIndex];

		boneAnimation[i] = matAnimation * matParentAnimation;
		renderTransform[i] = matInvBindPose * boneAnimation[i];
	}
}

void ModelAnimPlayer::Render()
{
	model->Buffer()->SetVSBuffer(2);

	for (ModelMesh* mesh : model->Meshes())
		mesh->Render();
}<file_sep>#include "Vector2.h"

#include <d3dx9math.h>
#include "Matrix.h"
#include "Quaternion.h"

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

const Vector2 Vector2::Zero = Vector2(0.0f, 0.0f);
const Vector2 Vector2::One = Vector2(1.0f, 1.0f);
const Vector2 Vector2::UnitX = Vector2(1.0f, 0.0f);
const Vector2 Vector2::UnitY = Vector2(0.0f, 1.0f);

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


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
//////////////////////////////////////////////////////////////////////////
Vector2::Vector2( void )
{
	this->X = 0.0f;
	this->Y = 0.0f;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
///@param value : x = y = value;
//////////////////////////////////////////////////////////////////////////
Vector2::Vector2( float value )
{
	this->X = this->Y = value;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
///@param x : X
///@param y : Y
//////////////////////////////////////////////////////////////////////////
Vector2::Vector2( float x, float y )
{
	this->X = x;
	this->Y = y;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief -
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector2 Vector2::operator-( void )
{
	Vector2 vector2;
	vector2.X = -this->X;
	vector2.Y = -this->Y;

	return vector2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief ==
///@param value2 : 벡터
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool Vector2::operator==( const Vector2& value2 ) const
{
	if((double)this->X == (double)value2.X)
		return (double)this->Y == (double)value2.Y;
	else
		return false;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief !=
///@param value2 : 벡터
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool Vector2::operator!=( const Vector2& value2 ) const
{
	if((double)this->X == (double)value2.X)
		return (double)this->Y != (double)value2.Y;
	else
		return true;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief +
///@param value2 : 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector2 Vector2::operator+( const Vector2& value2 ) const
{
	Vector2 vector2;
	vector2.X = this->X + value2.X;
	vector2.Y = this->Y + value2.Y;

	return vector2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief -
///@param value2 : 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector2 Vector2::operator-( const Vector2& value2 ) const
{
	Vector2 vector2;
	vector2.X = this->X - value2.X;
	vector2.Y = this->Y - value2.Y;

	return vector2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief *
///@param value2 : 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector2 Vector2::operator*( const Vector2& value2 ) const
{
	Vector2 vector2;
	vector2.X = this->X * value2.X;
	vector2.Y = this->Y * value2.Y;

	return vector2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief *
///@param scaleFactor : 값
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector2 Vector2::operator*( const float& scaleFactor ) const
{
	Vector2 vector2;
	vector2.X = this->X * scaleFactor;
	vector2.Y = this->Y * scaleFactor;

	return vector2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief /
///@param value2 : 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector2 Vector2::operator/( const Vector2& value2 ) const
{
	Vector2 vector2;
	vector2.X = this->X / value2.X;
	vector2.Y = this->Y / value2.Y;

	return vector2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief /
///@param divider : 값
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector2 Vector2::operator/( const float& divider ) const
{
	float num = 1.0f / divider;

	Vector2 vector2;
	vector2.X = this->X * num;
	vector2.Y = this->Y * num;

	return vector2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief +=
///@param value2 : 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
void Vector2::operator+=( const Vector2& value2 )
{
	*this = *this + value2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief -=
///@param value2 : 벡터 
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
void Vector2::operator-=( const Vector2& value2 )
{
	*this = *this - value2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief *=
///@param value2 : 벡터 
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
void Vector2::operator*=( const Vector2& value2 )
{
	*this = *this * value2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief /=
///@param scaleFactor : 값
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
void Vector2::operator*=( const float& scaleFactor )
{
	*this = *this * scaleFactor;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief /=
///@param value2 : 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
void Vector2::operator/=( const Vector2& value2 )
{
	*this = *this / value2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief /=
///@param divider : 값
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
void Vector2::operator/=( const float& divider )
{
	*this = *this / divider;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 문자열로 변환
///@return 문자열
//////////////////////////////////////////////////////////////////////////
std::string Vector2::ToString()
{
	std::string temp;
	char val[255];

	sprintf(val, "{X:%#f ", X); temp += val; 
	sprintf(val, "Y:%#f}", Y); temp += val;

	return temp;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief D3DXVECTOR2로 변환
///@return D3DX 벡터 
//////////////////////////////////////////////////////////////////////////
D3DXVECTOR2 Vector2::ToD3DXVECTOR2()
{
	D3DXVECTOR2 vector2;
	vector2.x = X;
	vector2.y = Y;

	return vector2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 크기 계산
///@return 결과 값
//////////////////////////////////////////////////////////////////////////
float Vector2::Length()
{
	return (float)sqrt((double)this->X * (double)this->X + (double)this->Y * (double)this->Y);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 제곱으로 크기 계산
///@return 결과 값
//////////////////////////////////////////////////////////////////////////
float Vector2::LengthSquared()
{
	return (float)((double)this->X * (double)this->X + (double)this->Y * (double)this->Y);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 정규화
//////////////////////////////////////////////////////////////////////////
void Vector2::Normalize()
{
	float num = 1.0f / (float)sqrt((double)this->X * (double)this->X + (double)this->Y * (double)this->Y);

	this->X *= num;
	this->Y *= num;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 거리계산
///@param value1 : 벡터1
///@param value2 : 벡터2
///@return 결과 값
//////////////////////////////////////////////////////////////////////////
float Vector2::Distance( Vector2 value1, Vector2 value2 )
{
	float num1 = value1.X - value2.X;
	float num2 = value1.Y - value2.Y;

	return (float)sqrt((double)num1 * (double)num1 + (double)num2 * (double)num2);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 제곱으로 거리계산
///@param value1 : 벡터1
///@param value2 : 벡터2
///@return 결과 값
//////////////////////////////////////////////////////////////////////////
float Vector2::DistanceSquared( Vector2 value1, Vector2 value2 )
{
	float num1 = value1.X - value2.X;
	float num2 = value1.Y - value2.Y;

	return (float)((double)num1 * (double)num1 + (double)num2 * (double)num2);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 내적 계산
///@param value1 : 벡터1
///@param value2 : 벡터2
///@return 결과 값
//////////////////////////////////////////////////////////////////////////
float Vector2::Dot( Vector2 value1, Vector2 value2 )
{
	return (float)((double)value1.X * (double)value2.X + (double)value1.Y * (double)value2.Y);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 정규화
///@param value : 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector2 Vector2::Normalize( Vector2 value )
{
	float num = 1.0f / (float)sqrt((double)value.X * (double)value.X + (double)value.Y * (double)value.Y);
	
	Vector2 vector2;
	vector2.X = value.X * num;
	vector2.Y = value.Y * num;

	return vector2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 반사값
///@param vector : 벡터
///@param normal : 노멀벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector2 Vector2::Reflect( Vector2 vector, Vector2 normal )
{
	float num = (float)((double)vector.X * (double)normal.X + (double)vector.Y * (double)normal.Y);

	Vector2 vector2;
	vector2.X = vector.X - 2.0f * num * normal.X;
	vector2.Y = vector.Y - 2.0f * num * normal.Y;

	return vector2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 두 벡터 중 작은 벡터
///@param value1 : 벡터1
///@param value2 : 벡터2
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector2 Vector2::Min( Vector2 value1, Vector2 value2 )
{
	Vector2 vector2;
	vector2.X = (double)value1.X < (double)value2.X ? value1.X : value2.X;
	vector2.Y = (double)value1.Y < (double)value2.Y ? value1.Y : value2.Y;

	return vector2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 두 벡터 중 큰 벡터
///@param value1 : 벡터1
///@param value2 : 벡터2
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector2 Vector2::Max( Vector2 value1, Vector2 value2 )
{
	Vector2 vector2;
	vector2.X = (double)value1.X > (double)value2.X ? value1.X : value2.X;
	vector2.Y = (double)value1.Y > (double)value2.Y ? value1.Y : value2.Y;

	return vector2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 해당 벡터가 최소값보다 작을 경우 최소값, 반대의 경우 최대값
///@param value1 : 벡터
///@param min : 최소값 벡터
///@param max : 최대값 벡터
//////////////////////////////////////////////////////////////////////////
Vector2 Vector2::Clamp( Vector2 value1, Vector2 min, Vector2 max )
{
	float num1 = value1.X;
	float num2 = (double) num1 > (double) max.X ? max.X : num1;
	float num3 = (double) num2 < (double) min.X ? min.X : num2;

	float num4 = value1.Y;
	float num5 = (double) num4 > (double) max.Y ? max.Y : num4;
	float num6 = (double) num5 < (double) min.Y ? min.Y : num5;

	Vector2 vector2;
	vector2.X = num3;
	vector2.Y = num6;

	return vector2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 두 벡터의 선형보간
///@param value1 : 벡터1
///@param value2 : 벡터2
///@param amount : 보간값
///@return 결과벡터
//////////////////////////////////////////////////////////////////////////
Vector2 Vector2::Lerp( Vector2 value1, Vector2 value2, float amount )
{
	Vector2 vector2;
	vector2.X = value1.X + (value2.X - value1.X) * amount;
	vector2.Y = value1.Y + (value2.Y - value1.Y) * amount;

	return vector2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 두 벡터를 부드럽게 보간
///@param value1 : 벡터1
///@param value2 : 벡터2
///@param amount : 보간값
///@return 결과벡터
//////////////////////////////////////////////////////////////////////////
Vector2 Vector2::SmoothStep( Vector2 value1, Vector2 value2, float amount )
{
	amount = (double)amount > 1.0 ? 1.0f : ((double)amount < 0.0 ? 0.0f : amount);
	amount = (float)((double)amount * (double)amount * (3.0 - 2.0 * (double)amount));

	Vector2 vector2;
	vector2.X = value1.X + (value2.X - value1.X) * amount;
	vector2.Y = value1.Y + (value2.Y - value1.Y) * amount;

	return vector2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 카트뮬-롬 보간
///@param value1 : 벡터1
///@param value2 : 벡터2
///@param value3 : 벡터3
///@param value4 : 벡터4
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector2 Vector2::CatmullRom( Vector2 value1, Vector2 value2, Vector2 value3, Vector2 value4, float amount )
{
	float num1 = amount * amount;
	float num2 = amount * num1;

	Vector2 vector2;
	vector2.X = (float)(0.5 * (2.0 * (double)value2.X + (-(double)value1.X + (double)value3.X)* (double)amount + (2.0 * (double)value1.X - 5.0 * (double)value2.X + 4.0 * (double)value3.X - (double)value4.X)* (double)num1 + (-(double)value1.X + 3.0 * (double)value2.X - 3.0 * (double)value3.X + (double)value4.X)* (double)num2));
	vector2.Y = (float)(0.5 * (2.0 * (double)value2.Y + (-(double)value1.Y + (double)value3.Y)* (double)amount + (2.0 * (double)value1.Y - 5.0 * (double)value2.Y + 4.0 * (double)value3.Y - (double)value4.Y)* (double)num1 + (-(double)value1.Y + 3.0 * (double)value2.Y - 3.0 * (double)value3.Y + (double)value4.Y)* (double)num2));

	return vector2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 에르미트 보간
///@param value1 : 벡터1
///@param tagent1 : 벡터1의 탄젠트 벡터
///@param value2 : 벡터2
///@param tagent2 : 벡터2 탄젠트 벡터
///@param amount : 보간값
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector2 Vector2::Hermite( Vector2 value1, Vector2 tangent1, Vector2 value2, Vector2 tangent2, float amount )
{
	float num1 = amount * amount;
	float num2 = amount * num1;
	float num3 = (float)(2.0 * (double)num2 - 3.0 * (double)num1 + 1.0);
	float num4 = (float)(-2.0 * (double)num2 + 3.0 * (double)num1);
	float num5 = num2 - 2.0f * num1 + amount;
	float num6 = num2 - num1;

	Vector2 vector2;
	vector2.X = (float)((double)value1.X * (double)num3 + (double)value2.X * (double)num4 + (double)tangent1.X * (double)num5 + (double)tangent2.X * (double)num6);
	vector2.Y = (float)((double)value1.Y * (double)num3 + (double)value2.Y * (double)num4 + (double)tangent1.Y * (double)num5 + (double)tangent2.Y * (double)num6);

	return vector2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 매트릭스에 의한 벡터 변환
///@param position : 벡터
///@param matrix : 매트릭스
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector2 Vector2::Transform( Vector2 position, Matrix matrix )
{
	float num1 = (float)((double)position.X * (double)matrix.M11 + (double)position.Y * (double)matrix.M21) + matrix.M41;
	float num2 = (float)((double)position.X * (double)matrix.M12 + (double)position.Y * (double)matrix.M22) + matrix.M42;

	Vector2 vector2;
	vector2.X = num1;
	vector2.Y = num2;

	return vector2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 쿼터니온에 의한 벡터변환
///@param value : 벡터
//////////////////////////////////////////////////////////////////////////
Vector2 Vector2::Transform( Vector2 value, Quaternion rotation )
{
	float num1 = rotation.X + rotation.X;
	float num2 = rotation.Y + rotation.Y;
	float num3 = rotation.Z + rotation.Z;

	float num4 = rotation.W * num3;
	float num5 = rotation.X * num1;
	float num6 = rotation.X * num2;
	float num7 = rotation.Y * num2;
	float num8 = rotation.Z * num3;

	float num9 = (float) ((double) value.X * (1.0 - (double) num7 - (double) num8) + (double) value.Y * ((double) num6 - (double) num4));
	float num10 = (float) ((double) value.X * ((double) num6 + (double) num4) + (double) value.Y * (1.0 - (double) num5 - (double) num8));

	Vector2 vector2;
	vector2.X = num9;
	vector2.Y = num10;

	return vector2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 매트릭스에 의한 노멀벡터 변환
///@param normal : 법선 벡터
///@param matrix : 매트릭스
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector2 Vector2::TransformNormal( Vector2 normal, Matrix matrix )
{
	float num1 = (float)((double)normal.X * (double)matrix.M11 + (double)normal.Y * (double)matrix.M21);
	float num2 = (float)((double)normal.X * (double)matrix.M12 + (double)normal.Y * (double)matrix.M22);

	Vector2 vector2;
	vector2.X = num1;
	vector2.Y = num2;

	return vector2;
}<file_sep>#pragma once
#include "../Objects/GameAnimationModel.h"

class GameUnit : public GameAnimationModel
{
public:
	GameUnit(wstring matFile, wstring meshFile);
	virtual ~GameUnit();

	virtual void Update();
	virtual void Render();
};<file_sep>#include "Vector4.h"

#include <d3dx9math.h>
#include "Vector2.h"
#include "Vector3.h"
#include "Matrix.h"
#include "Quaternion.h"

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

const Vector4 Vector4::Zero = Vector4(0.0f, 0.0f, 0.0f, 0.0f);
const Vector4 Vector4::One = Vector4(1.0f, 1.0f, 1.0f, 1.0f);

const Vector4 Vector4::UnitX = Vector4(1.0f, 0.0f, 0.0f, 0.0f);
const Vector4 Vector4::UnitY = Vector4(0.0f, 1.0f, 0.0f, 0.0f);
const Vector4 Vector4::UnitZ = Vector4(0.0f, 0.0f, 1.0f, 0.0f);
const Vector4 Vector4::UnitW = Vector4(0.0f, 0.0f, 0.0f, 1.0f);

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


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
//////////////////////////////////////////////////////////////////////////
Vector4::Vector4( void )
{
	this->X = 0.0f;
	this->Y = 0.0f;
	this->Z = 0.0f;
	this->W = 0.0f;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
///@param x : X
///@param y : Y
///@param z : Z
///@param w : W
//////////////////////////////////////////////////////////////////////////
Vector4::Vector4( float x, float y, float z, float w )
{
	this->X = x;
	this->Y = y;
	this->Z = z;
	this->W = w;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
///@param value : x, y
///@param z : Z
///@param w : W
//////////////////////////////////////////////////////////////////////////
Vector4::Vector4( Vector2 value, float z, float w )
{
	this->X = value.X;
	this->Y = value.Y;
	this->Z = z;
	this->W = w;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
///@param value : x, y, z
///@param w : W
//////////////////////////////////////////////////////////////////////////
Vector4::Vector4( Vector3 value, float w )
{
	this->X = value.X;
	this->Y = value.Y;
	this->Z = value.Z;
	this->W = w;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
///@param x = y = z = w = value
//////////////////////////////////////////////////////////////////////////
Vector4::Vector4( float value )
{
	this->X = this->Y = this->Z = this->W = value;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief -
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector4 Vector4::operator-( void )
{
	Vector4 vector4;
	vector4.X = -this->X;
	vector4.Y = -this->Y;
	vector4.Z = -this->Z;
	vector4.W = -this->W;

	return vector4;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief ==
///@param value2 : 벡터
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool Vector4::operator==( const Vector4& value2 ) const
{
	if ((double)this->X == (double)value2.X && (double)this->Y == (double)value2.Y && (double)this->Z == (double)value2.Z)
		return (double)this->W == (double)value2.W;
	else
		return false;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief !=
///@param value2 : 벡터
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool Vector4::operator!=( const Vector4& value2 ) const
{
	if ((double)this->X == (double)value2.X && (double)this->Y == (double)value2.Y && (double)this->Z == (double)value2.Z)
		return (double)this->W != (double)value2.W;
	else
		return true;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief +
///@param value2 : 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector4 Vector4::operator+( const Vector4& value2 ) const
{
	Vector4 vector4;
	vector4.X = this->X + value2.X;
	vector4.Y = this->Y + value2.Y;
	vector4.Z = this->Z + value2.Z;
	vector4.W = this->W + value2.W;

	return vector4;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief -
///@param value2 : 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector4 Vector4::operator-( const Vector4& value2 ) const
{
	Vector4 vector4;
	vector4.X = this->X - value2.X;
	vector4.Y = this->Y - value2.Y;
	vector4.Z = this->Z - value2.Z;
	vector4.W = this->W - value2.W;

	return vector4;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief *
///@param value2 : 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector4 Vector4::operator*( const Vector4& value2 ) const
{
	Vector4 vector4;
	vector4.X = this->X * value2.X;
	vector4.Y = this->Y * value2.Y;
	vector4.Z = this->Z * value2.Z;
	vector4.W = this->W * value2.W;

	return vector4;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief *
///@param scaleFactor : 값
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector4 Vector4::operator*( const float& scaleFactor ) const
{
	Vector4 vector4;
	vector4.X = this->X * scaleFactor;
	vector4.Y = this->Y * scaleFactor;
	vector4.Z = this->Z * scaleFactor;
	vector4.W = this->W * scaleFactor;

	return vector4;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief /
///@param value2 : 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector4 Vector4::operator/( const Vector4& value2 ) const
{
	Vector4 vector4;
	vector4.X = this->X / value2.X;
	vector4.Y = this->Y / value2.Y;
	vector4.Z = this->Z / value2.Z;
	vector4.W = this->W / value2.W;

	return vector4;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief /
///@param divider : 값
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector4 Vector4::operator/( const float& divider ) const
{
	float num = 1.0f / divider;

	Vector4 vector4;
	vector4.X = this->X * num;
	vector4.Y = this->Y * num;
	vector4.Z = this->Z * num;
	vector4.W = this->W * num;

	return vector4;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief +=
///@param value2 : 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
void Vector4::operator+=( const Vector4& value2 )
{
	*this = *this + value2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief -=
///@param value2 : 벡터 
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
void Vector4::operator-=( const Vector4& value2 )
{
	*this = *this - value2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief *=
///@param value2 : 벡터 
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
void Vector4::operator*=( const Vector4& value2 )
{
	*this = *this * value2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief /=
///@param scaleFactor : 값
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
void Vector4::operator*=( const float& scaleFactor )
{
	*this = *this * scaleFactor;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief /=
///@param value2 : 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
void Vector4::operator/=( const Vector4& value2 )
{
	*this = *this / value2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief /=
///@param divider : 값
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
void Vector4::operator/=( const float& divider )
{
	*this = *this / divider;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 문자열로 변환
///@return 문자열
//////////////////////////////////////////////////////////////////////////
std::string Vector4::ToString()
{
	std::string temp;
	char val[255];

	sprintf(val, "{X:%#f ", X); temp += val; 
	sprintf(val, "Y:%#f ", Y); temp += val;
	sprintf(val, "Z:%#f ", Z); temp += val;
	sprintf(val, "W:%#f}", W); temp += val;

	return temp;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief D3DXVECTOR4로 변환
///@return D3DX 벡터 
//////////////////////////////////////////////////////////////////////////
D3DXVECTOR4 Vector4::ToD3DXVECTOR4()
{
	D3DXVECTOR4 vector4;
	vector4.x = X;
	vector4.y = Y;
	vector4.z = Z;
	vector4.z = W;

	return vector4;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 크기 계산
///@return 결과 값
//////////////////////////////////////////////////////////////////////////
float Vector4::Length()
{
	return (float)sqrt((double)this->X * (double)this->X + (double)this->Y * (double)this->Y + (double)this->Z * (double)this->Z + (double)this->W * (double)this->W);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 제곱으로 크기 계산
///@return 결과 값
//////////////////////////////////////////////////////////////////////////
float Vector4::LengthSquared()
{
	return (float)((double)this->X * (double)this->X + (double)this->Y * (double)this->Y + (double)this->Z * (double)this->Z + (double)this->W * (double)this->W);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 정규화
//////////////////////////////////////////////////////////////////////////
void Vector4::Normalize()
{
	float num = 1.0f / (float)sqrt((double)this->X * (double)this->X + (double)this->Y * (double)this->Y + (double)this->Z * (double)this->Z + (double)this->W * (double)this->W);

	this->X *= num;
	this->Y *= num;
	this->Z *= num;
	this->W *= num;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 거리계산
///@param value1 : 벡터1
///@param value2 : 벡터2
///@return 결과 값
//////////////////////////////////////////////////////////////////////////
float Vector4::Distance( Vector4 value1, Vector4 value2 )
{
	float num1 = value1.X - value2.X;
	float num2 = value1.Y - value2.Y;
	float num3 = value1.Z - value2.Z;
	float num4 = value1.W - value2.W;

	return (float)sqrt((double)num1 * (double)num1 + (double)num2 * (double)num2 + (double)num3 * (double)num3 + (double)num4 * (double)num4);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 제곱으로 거리계산
///@param value1 : 벡터1
///@param value2 : 벡터2
///@return 결과 값
//////////////////////////////////////////////////////////////////////////
float Vector4::DistanceSquared( Vector4 value1, Vector4 value2 )
{
	float num1 = value1.X - value2.X;
	float num2 = value1.Y - value2.Y;
	float num3 = value1.Z - value2.Z;
	float num4 = value1.W - value2.W;

	return (float)((double)num1 * (double)num1 + (double)num2 * (double)num2 + (double)num3 * (double)num3 + (double)num4 * (double)num4);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 내적 계산
///@param value1 : 벡터1
///@param value2 : 벡터2
///@return 결과 값
//////////////////////////////////////////////////////////////////////////
float Vector4::Dot( Vector4 value1, Vector4 value2 )
{
	return (float)((double)value1.X * (double)value2.X + (double)value1.Y * (double)value2.Y + (double)value1.Z * (double)value2.Z + (double)value1.W * (double)value2.W);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 정규화
///@param value : 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector4 Vector4::Normalize( Vector4 value )
{
	float num = 1.0f / (float)sqrt((double)value.X * (double)value.X + (double)value.Y * (double)value.Y + (double)value.Z * (double)value.Z + (double)value.W * (double)value.W);

	Vector4 vector4;
	vector4.X = value.X * num;
	vector4.Y = value.Y * num;
	vector4.Z = value.Z * num;
	vector4.W = value.W * num;

	return vector4;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 두 벡터 중 작은 벡터
///@param value1 : 벡터1
///@param value2 : 벡터2
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector4 Vector4::Min( Vector4 value1, Vector4 value2 )
{
	Vector4 vector4;
	vector4.X = (double)value1.X < (double)value2.X ? value1.X : value2.X;
	vector4.Y = (double)value1.Y < (double)value2.Y ? value1.Y : value2.Y;
	vector4.Z = (double)value1.Z < (double)value2.Z ? value1.Z : value2.Z;
	vector4.W = (double)value1.W < (double)value2.W ? value1.W : value2.W;

	return vector4;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 두 벡터 중 큰 벡터
///@param value1 : 벡터1
///@param value2 : 벡터2
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector4 Vector4::Max( Vector4 value1, Vector4 value2 )
{
	Vector4 vector4;
	vector4.X = (double)value1.X > (double)value2.X ? value1.X : value2.X;
	vector4.Y = (double)value1.Y > (double)value2.Y ? value1.Y : value2.Y;
	vector4.Z = (double)value1.Z > (double)value2.Z ? value1.Z : value2.Z;
	vector4.W = (double)value1.W > (double)value2.W ? value1.W : value2.W;

	return vector4;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 해당 벡터가 최소값보다 작을 경우 최소값, 반대의 경우 최대값
///@param value1 : 벡터
///@param min : 최소값 벡터
///@param max : 최대값 벡터
//////////////////////////////////////////////////////////////////////////
Vector4 Vector4::Clamp( Vector4 value1, Vector4 min, Vector4 max )
{
	float num1 = value1.X;
	float num2 = (double)num1 > (double)max.X ? max.X : num1;
	float num3 = (double)num2 < (double)min.X ? min.X : num2;

	float num4 = value1.Y;
	float num5 = (double)num4 > (double)max.Y ? max.Y : num4;
	float num6 = (double)num5 < (double)min.Y ? min.Y : num5;

	float num7 = value1.Z;
	float num8 = (double)num7 > (double)max.Z ? max.Z : num7;
	float num9 = (double)num8 < (double)min.Z ? min.Z : num8;

	float num10 = value1.W;
	float num11 = (double)num10 > (double)max.W ? max.W : num10;
	float num12 = (double)num11 < (double)min.W ? min.W : num11;

	Vector4 vector4;
	vector4.X = num3;
	vector4.Y = num6;
	vector4.Z = num9;
	vector4.W = num12;

	return vector4;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 두 벡터의 선형보간
///@param value1 : 벡터1
///@param value2 : 벡터2
///@param amount : 보간값
///@return 결과벡터
//////////////////////////////////////////////////////////////////////////
Vector4 Vector4::Lerp( Vector4 value1, Vector4 value2, float amount )
{
	Vector4 vector4;
	vector4.X = value1.X + (value2.X - value1.X) * amount;
	vector4.Y = value1.Y + (value2.Y - value1.Y) * amount;
	vector4.Z = value1.Z + (value2.Z - value1.Z) * amount;
	vector4.W = value1.W + (value2.W - value1.W) * amount;

	return vector4;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 두 벡터를 부드럽게 보간
///@param value1 : 벡터1
///@param value2 : 벡터2
///@param amount : 보간값
///@return 결과벡터
//////////////////////////////////////////////////////////////////////////
Vector4 Vector4::SmoothStep( Vector4 value1, Vector4 value2, float amount )
{
	amount = (double)amount > 1.0 ? 1.0f : ((double)amount < 0.0 ? 0.0f : amount);
	amount = (float)((double)amount * (double)amount * (3.0 - 2.0 * (double)amount));

	Vector4 vector4;
	vector4.X = value1.X + (value2.X - value1.X) * amount;
	vector4.Y = value1.Y + (value2.Y - value1.Y) * amount;
	vector4.Z = value1.Z + (value2.Z - value1.Z) * amount;
	vector4.W = value1.W + (value2.W - value1.W) * amount;

	return vector4;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 카트뮬-롬 보간
///@param value1 : 벡터1
///@param value2 : 벡터2
///@param value3 : 벡터3
///@param value4 : 벡터4
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector4 Vector4::CatmullRom( Vector4 value1, Vector4 value2, Vector4 value3, Vector4 value4, float amount )
{
	float num1 = amount * amount;
	float num2 = amount * num1;

	Vector4 vector4;
	vector4.X = (float)(0.5 * (2.0 * (double)value2.X + (-(double)value1.X + (double)value3.X)* (double)amount + (2.0 * (double)value1.X - 5.0 * (double)value2.X + 4.0 * (double)value3.X - (double)value4.X)* (double)num1 + (-(double)value1.X + 3.0 * (double)value2.X - 3.0 * (double)value3.X + (double)value4.X)* (double)num2));
	vector4.Y = (float)(0.5 * (2.0 * (double)value2.Y + (-(double)value1.Y + (double)value3.Y)* (double)amount + (2.0 * (double)value1.Y - 5.0 * (double)value2.Y + 4.0 * (double)value3.Y - (double)value4.Y)* (double)num1 + (-(double)value1.Y + 3.0 * (double)value2.Y - 3.0 * (double)value3.Y + (double)value4.Y)* (double)num2));
	vector4.Z = (float)(0.5 * (2.0 * (double)value2.Z + (-(double)value1.Z + (double)value3.Z)* (double)amount + (2.0 * (double)value1.Z - 5.0 * (double)value2.Z + 4.0 * (double)value3.Z - (double)value4.Z)* (double)num1 + (-(double)value1.Z + 3.0 * (double)value2.Z - 3.0 * (double)value3.Z + (double)value4.Z)* (double)num2));
	vector4.W = (float)(0.5 * (2.0 * (double)value2.W + (-(double)value1.W + (double)value3.W)* (double)amount + (2.0 * (double)value1.W - 5.0 * (double)value2.W + 4.0 * (double)value3.W - (double)value4.W)* (double)num1 + (-(double)value1.W + 3.0 * (double)value2.W - 3.0 * (double)value3.W + (double)value4.W)* (double)num2));

	return vector4;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 에르미트 보간
///@param value1 : 벡터1
///@param tagent1 : 벡터1의 탄젠트 벡터
///@param value2 : 벡터2
///@param tagent2 : 벡터2 탄젠트 벡터
///@param amount : 보간값
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector4 Vector4::Hermite( Vector4 value1, Vector4 tangent1, Vector4 value2, Vector4 tangent2, float amount )
{
	float num1 = amount * amount;
	float num2 = amount * num1;
	float num3 = (float)(2.0 * (double)num2 - 3.0 * (double)num1 + 1.0);
	float num4 = (float)(-2.0 * (double)num2 + 3.0 * (double)num1);
	float num5 = num2 - 2.0f * num1 + amount;
	float num6 = num2 - num1;

	Vector4 vector4;
	vector4.X = (float)((double)value1.X * (double)num3 + (double)value2.X * (double)num4 + (double)tangent1.X * (double)num5 + (double)tangent2.X * (double)num6);
	vector4.Y = (float)((double)value1.Y * (double)num3 + (double)value2.Y * (double)num4 + (double)tangent1.Y * (double)num5 + (double)tangent2.Y * (double)num6);
	vector4.Z = (float)((double)value1.Z * (double)num3 + (double)value2.Z * (double)num4 + (double)tangent1.Z * (double)num5 + (double)tangent2.Z * (double)num6);
	vector4.W = (float)((double)value1.W * (double)num3 + (double)value2.W * (double)num4 + (double)tangent1.W * (double)num5 + (double)tangent2.W * (double)num6);

	return vector4;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 매트릭스에 의한 2D벡터 변환
///@param position : 벡터
///@param matrix : 매트릭스
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector4 Vector4::Transform( Vector2 position, Matrix matrix )
{
	float num1 = (float)((double)position.X * (double)matrix.M11 + (double)position.Y * (double)matrix.M21) + matrix.M41;
	float num2 = (float)((double)position.X * (double)matrix.M12 + (double)position.Y * (double)matrix.M22) + matrix.M42;
	float num3 = (float)((double)position.X * (double)matrix.M13 + (double)position.Y * (double)matrix.M23) + matrix.M43;
	float num4 = (float)((double)position.X * (double)matrix.M14 + (double)position.Y * (double)matrix.M24) + matrix.M44;

	Vector4 vector4;
	vector4.X = num1;
	vector4.Y = num2;
	vector4.Z = num3;
	vector4.W = num4;

	return vector4;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 매트릭스에 의한 3D벡터 변환
///@param position : 벡터
///@param matrix : 매트릭스
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector4 Vector4::Transform( Vector3 position, Matrix matrix )
{
	float num1 = (float)((double)position.X * (double)matrix.M11 + (double)position.Y * (double)matrix.M21 + (double)position.Z * (double)matrix.M31) + matrix.M41;
	float num2 = (float)((double)position.X * (double)matrix.M12 + (double)position.Y * (double)matrix.M22 + (double)position.Z * (double)matrix.M32) + matrix.M42;
	float num3 = (float)((double)position.X * (double)matrix.M13 + (double)position.Y * (double)matrix.M23 + (double)position.Z * (double)matrix.M33) + matrix.M43;
	float num4 = (float)((double)position.X * (double)matrix.M14 + (double)position.Y * (double)matrix.M24 + (double)position.Z * (double)matrix.M34) + matrix.M44;

	Vector4 vector4;
	vector4.X = num1;
	vector4.Y = num2;
	vector4.Z = num3;
	vector4.W = num4;

	return vector4;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 매트릭스에 의한 4D벡터 변환
///@param position : 벡터
///@param matrix : 매트릭스
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector4 Vector4::Transform( Vector4 vector, Matrix matrix )
{
	float num1 = (float)((double)vector.X * (double)matrix.M11 + (double)vector.Y * (double)matrix.M21 + (double)vector.Z * (double)matrix.M31 + (double)vector.W * (double)matrix.M41);
	float num2 = (float)((double)vector.X * (double)matrix.M12 + (double)vector.Y * (double)matrix.M22 + (double)vector.Z * (double)matrix.M32 + (double)vector.W * (double)matrix.M42);
	float num3 = (float)((double)vector.X * (double)matrix.M13 + (double)vector.Y * (double)matrix.M23 + (double)vector.Z * (double)matrix.M33 + (double)vector.W * (double)matrix.M43);
	float num4 = (float)((double)vector.X * (double)matrix.M14 + (double)vector.Y * (double)matrix.M24 + (double)vector.Z * (double)matrix.M34 + (double)vector.W * (double)matrix.M44);
	
	Vector4 vector4;
	vector4.X = num1;
	vector4.Y = num2;
	vector4.Z = num3;
	vector4.W = num4;

	return vector4;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 쿼터니온에 의한 2D벡터 변환
///@param value : 벡터
///@param rotation : 쿼터니온
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector4 Vector4::Transform( Vector2 value, Quaternion rotation )
{
	float num1 = rotation.X + rotation.X;
	float num2 = rotation.Y + rotation.Y;
	float num3 = rotation.Z + rotation.Z;

	float num4 = rotation.W * num1;
	float num5 = rotation.W * num2;
	float num6 = rotation.W * num3;
	float num7 = rotation.X * num1;
	float num8 = rotation.X * num2;
	float num9 = rotation.X * num3;

	float num10 = rotation.Y * num2;
	float num11 = rotation.Y * num3;
	float num12 = rotation.Z * num3;

	float num13 = (float)((double)value.X * (1.0 - (double)num10 - (double)num12)+ (double)value.Y * ((double)num8 - (double)num6));
	float num14 = (float)((double)value.X * ((double)num8 + (double)num6) + (double)value.Y * (1.0 - (double)num7 - (double)num12));
	float num15 = (float)((double)value.X * ((double)num9 - (double)num5) + (double)value.Y * ((double)num11 + (double)num4));
	
	Vector4 vector4;
	vector4.X = num13;
	vector4.Y = num14;
	vector4.Z = num15;
	vector4.W = 1.0f;
	return vector4;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 쿼터니온에 의한 3D벡터 변환
///@param value : 벡터
///@param rotation : 쿼터니온
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector4 Vector4::Transform( Vector3 value, Quaternion rotation )
{
	float num1 = rotation.X + rotation.X;
	float num2 = rotation.Y + rotation.Y;
	float num3 = rotation.Z + rotation.Z;

	float num4 = rotation.W * num1;
	float num5 = rotation.W * num2;
	float num6 = rotation.W * num3;
	float num7 = rotation.X * num1;
	float num8 = rotation.X * num2;
	float num9 = rotation.X * num3;

	float num10 = rotation.Y * num2;
	float num11 = rotation.Y * num3;
	float num12 = rotation.Z * num3;

	float num13 = (float)((double)value.X * (1.0 - (double)num10 - (double)num12)+ (double)value.Y * ((double)num8 - (double)num6)+ (double)value.Z * ((double)num9 + (double)num5));
	float num14 = (float)((double)value.X * ((double)num8 + (double)num6)+ (double)value.Y * (1.0 - (double)num7 - (double)num12)+ (double)value.Z * ((double)num11 - (double)num4));
	float num15 = (float)((double)value.X * ((double)num9 - (double)num5)+ (double)value.Y * ((double)num11 + (double)num4)+ (double)value.Z * (1.0 - (double)num7 - (double)num10));

	Vector4 vector4;
	vector4.X = num13;
	vector4.Y = num14;
	vector4.Z = num15;
	vector4.W = 1.0f;

	return vector4;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 쿼터니온에 의한 4D벡터 변환
///@param value : 벡터
///@param rotation : 쿼터니온
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector4 Vector4::Transform( Vector4 value, Quaternion rotation )
{
	float num1 = rotation.X + rotation.X;
	float num2 = rotation.Y + rotation.Y;
	float num3 = rotation.Z + rotation.Z;

	float num4 = rotation.W * num1;
	float num5 = rotation.W * num2;
	float num6 = rotation.W * num3;
	float num7 = rotation.X * num1;
	float num8 = rotation.X * num2;
	float num9 = rotation.X * num3;

	float num10 = rotation.Y * num2;
	float num11 = rotation.Y * num3;
	float num12 = rotation.Z * num3;

	float num13 = (float)((double)value.X * (1.0 - (double)num10 - (double)num12)+ (double)value.Y * ((double)num8 - (double)num6)+ (double)value.Z * ((double)num9 + (double)num5));
	float num14 = (float)((double)value.X * ((double)num8 + (double)num6)+ (double)value.Y * (1.0 - (double)num7 - (double)num12)+ (double)value.Z * ((double)num11 - (double)num4));
	float num15 = (float)((double)value.X * ((double)num9 - (double)num5)+ (double)value.Y * ((double)num11 + (double)num4)+ (double)value.Z * (1.0 - (double)num7 - (double)num10));

	Vector4 vector4;
	vector4.X = num13;
	vector4.Y = num14;
	vector4.Z = num15;
	vector4.W = value.W;
	
	return vector4;
}<file_sep>#pragma once
#include "stdafx.h"

template<typename T>
class Singleton
{
public:
	static T* Get()
	{
		if (instance == nullptr)
			instance = new T();

		return instance;
	}
	static void Delete()
	{
		SAFE_DELETE(instance);
	}
protected:
	Singleton() {};
	virtual ~Singleton() { SAFE_DELETE(instance); }

private:
	static T* instance;
};

template <typename T> T* Singleton<T>::instance = nullptr;<file_sep>#include "stdafx.h"
#include "GameUnit.h"

GameUnit::GameUnit(wstring matFile, wstring meshFile)
	: GameAnimationModel(matFile, meshFile)
{

}

GameUnit::~GameUnit()
{

}

void GameUnit::Update()
{
	GameAnimationModel::Update();
}

void GameUnit::Render()
{
	GameAnimationModel::Render();
}
<file_sep>#pragma once

#include <string>
#pragma warning( disable : 4996)

struct D3DXVECTOR2;
class Matrix;
class Quaternion;

//////////////////////////////////////////////////////////////////////////
///@brief 2D 벡터
//////////////////////////////////////////////////////////////////////////
class Vector2
{
public:
	Vector2(void);
	Vector2(float value);
	Vector2(float x, float y);

	Vector2 operator -(void);

	bool operator ==(const Vector2& value2) const;
	bool operator !=(const Vector2& value2) const;

	Vector2 operator +(const Vector2& value2) const;
	Vector2 operator -(const Vector2& value2) const;
	Vector2 operator *(const Vector2& value2) const;
	Vector2 operator *(const float& scaleFactor) const;
	Vector2 operator /(const Vector2& value2) const;
	Vector2 operator /(const float& divider) const;

	void operator +=(const Vector2& value2);
	void operator -=(const Vector2& value2);
	void operator *=(const Vector2& value2);
	void operator *=(const float& scaleFactor);
	void operator /=(const Vector2& value2);
	void operator /=(const float& divider);


	//////////////////////////////////////////////////////////////////////////
	///@brief float형의 *연산 처리
	///@param scalefactor : 값
	///@param value2 : 벡터
	///@return 결과 벡터
	//////////////////////////////////////////////////////////////////////////
	friend Vector2 operator *(const float scaleFactor, const Vector2& value2)
	{
		return value2 * scaleFactor;
	}
	//////////////////////////////////////////////////////////////////////////


	std::string ToString();
	D3DXVECTOR2 ToD3DXVECTOR2();

	float Length();
	float LengthSquared();

	void Normalize();

	static float Distance(Vector2 value1, Vector2 value2);
	static float DistanceSquared(Vector2 value1, Vector2 value2);

	static float Dot(Vector2 value1, Vector2 value2);
	static Vector2 Normalize(Vector2 value);

	static Vector2 Reflect(Vector2 vector, Vector2 normal);

	static Vector2 Min(Vector2 value1, Vector2 value2);
	static Vector2 Max(Vector2 value1, Vector2 value2);
	static Vector2 Clamp(Vector2 value1, Vector2 min, Vector2 max);

	static Vector2 Lerp(Vector2 value1, Vector2 value2, float amount);
	static Vector2 SmoothStep(Vector2 value1, Vector2 value2, float amount);
	static Vector2 CatmullRom(Vector2 value1, Vector2 value2, Vector2 value3, Vector2 value4, float amount);
	static Vector2 Hermite(Vector2 value1, Vector2 tangent1, Vector2 value2, Vector2 tangent2, float amount);

	static Vector2 Transform(Vector2 position, Matrix matrix);
	static Vector2 Transform(Vector2 value, Quaternion rotation);
	static Vector2 TransformNormal(Vector2 normal, Matrix matrix);

public:
	const static Vector2 Zero;///< 0.0f, 0.0f
	const static Vector2 One;///< 1.0f, 1.0f

	const static Vector2 UnitX;///< 1.0f, 0.0f
	const static Vector2 UnitY;///< 0.0f, 1.0f

	float X;///< X
	float Y;///< Y
};<file_sep>#include "Gjk.h"

#include "../Core/MathHelper.h"

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

const int Gjk::BitsToIndices[16] = {0, 1, 2, 17, 3, 25, 26, 209, 4, 33, 34, 273, 35, 281, 282, 2257};

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


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
//////////////////////////////////////////////////////////////////////////
Gjk::Gjk( void )
{

}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 심플렉스가 가득찼는지 여부
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool Gjk::FullSimplex() const
{
	return simplexBits == 15;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 제곱으로 계산한 크기 중 가장 큰 값
///@return 결과 값
//////////////////////////////////////////////////////////////////////////
float Gjk::MaxLengthSquared() const
{
	return maxLengthSq;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 가까운 위치 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Gjk::ClosestPoint() const
{
	return closestPoint;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 리셋
//////////////////////////////////////////////////////////////////////////
void Gjk::Reset()
{
	simplexBits = 0;
	maxLengthSq = 0.0f;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 검사할 포인트 추가
///@return 추가 결과
//////////////////////////////////////////////////////////////////////////
bool Gjk::AddSupportPoint( Vector3 newPoint )
{
	int index1 = (BitsToIndices[simplexBits ^ 15] & 7) - 1;
	y[index1] = newPoint;
	yLengthSq[index1] = newPoint.LengthSquared();

	int num = BitsToIndices[simplexBits];
	while(num != 0)
	{
		int index2 = (num & 7) - 1;
		Vector3 vector3 = y[index2] - newPoint;

		edges[index2][index1] = vector3;
		edges[index1][index2] = -vector3;
		edgeLengthSq[index1][index2] = edgeLengthSq[index2][index1] = vector3.LengthSquared();
		num >>= 3;
	}
	UpdateDeterminant(index1);

	return UpdateSimplex(index1);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 행렬식 업데이트
///@param xmIdx : 갱신할 Determinant 번호
//////////////////////////////////////////////////////////////////////////
void Gjk::UpdateDeterminant( int index )
{
	int index1 = 1 << index;
	det[index1][index] = 1.0f;

	int num1 = Gjk::BitsToIndices[simplexBits];
	int num2 = num1;
	int num3 = 0;
	while(num2 != 0)
	{
		int index2 = (num2 & 7)- 1;
		int num4 = 1 << index2;
		int index3 = num4 | index1;
		det[index3][index2] = Dot(edges[index][index2], y[index]);
		det[index3][index] = Dot(edges[index2][index], y[index2]);
		
		int num5 = num1;
		for(int index4 = 0; index4 < num3; ++index4)
		{
			int index5 = (num5 & 7)- 1;
			int num6 = 1 << index5;
			int index6 = index3 | num6;
			
			int index7 = (double)edgeLengthSq[index2][index5] < (double)edgeLengthSq[index][index5] ? index2 : index;
			det[index6][index5] = (float)((double)det[index3][index2] * (double)Dot(edges[index7][index5], y[index2]) + (double)det[index3][index] * (double)Dot(edges[index7][index5], y[index]));
			
			int index8 = (double)edgeLengthSq[index5][index2] < (double)edgeLengthSq[index][index2] ? index5 : index;
			det[index6][index2] = (float)((double)det[num6 | index1][index5] * (double)Dot(edges[index8][index2], y[index5])+ (double)det[num6 | index1][index] * (double)Dot(edges[index8][index2], y[index]));
			
			int index9 = (double)edgeLengthSq[index2][index] < (double)edgeLengthSq[index5][index] ? index2 : index5;
			det[index6][index] = (float)((double)det[num4 | num6][index5] * (double)Dot(edges[index9][index], y[index5])+ (double)det[num4 | num6][index2] * (double)Dot(edges[index9][index], y[index2]));
			
			num5 >>= 3;
		}
		
		num2 >>= 3;
		++num3;
	}

	if((simplexBits | index1)== 15)
	{
		int index2 = (double)edgeLengthSq[1][0] < (double)edgeLengthSq[2][0] ? ((double)edgeLengthSq[1][0] < (double)edgeLengthSq[3][0] ? 1 : 3): ((double)edgeLengthSq[2][0] < (double)edgeLengthSq[3][0] ? 2 : 3);
		det[15][0] = (float)((double)det[14][1] * (double)Dot(edges[index2][0], y[1])+ (double)det[14][2] * (double)Dot(edges[index2][0], y[2])+ (double)det[14][3] * (double)Dot(edges[index2][0], y[3]));
		
		int index3 = (double)edgeLengthSq[0][1] < (double)edgeLengthSq[2][1] ? ((double)edgeLengthSq[0][1] < (double)edgeLengthSq[3][1] ? 0 : 3): ((double)edgeLengthSq[2][1] < (double)edgeLengthSq[3][1] ? 2 : 3);
		det[15][1] = (float)((double)det[13][0] * (double)Dot(edges[index3][1], y[0])+ (double)det[13][2] * (double)Dot(edges[index3][1], y[2])+ (double)det[13][3] * (double)Dot(edges[index3][1], y[3]));
		
		int index4 = (double)edgeLengthSq[0][2] < (double)edgeLengthSq[1][2] ? ((double)edgeLengthSq[0][2] < (double)edgeLengthSq[3][2] ? 0 : 3): ((double)edgeLengthSq[1][2] < (double)edgeLengthSq[3][2] ? 1 : 3);
		det[15][2] = (float)((double)det[11][0] * (double)Dot(edges[index4][2], y[0])+ (double)det[11][1] * (double)Dot(edges[index4][2], y[1])+ (double)det[11][3] * (double)Dot(edges[index4][2], y[3]));
		
		int index5 = (double)edgeLengthSq[0][3] < (double)edgeLengthSq[1][3] ? ((double)edgeLengthSq[0][3] < (double)edgeLengthSq[2][3] ? 0 : 2): ((double)edgeLengthSq[1][3] < (double)edgeLengthSq[2][3] ? 1 : 2);
		det[15][3] = (float)((double)det[7][0] * (double)Dot(edges[index5][3], y[0])+ (double)det[7][1] * (double)Dot(edges[index5][3], y[1])+ (double)det[7][2] * (double)Dot(edges[index5][3], y[2]));
	}
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 심플렉스 업데이트
///@param newIndex : 새로 업데이트할 인덱스
//////////////////////////////////////////////////////////////////////////
bool Gjk::UpdateSimplex( int newIndex )
{
	int yBits = simplexBits | 1 << newIndex;
	int xBits = 1 << newIndex;
	for(int index = simplexBits; index != 0; --index)
	{
		if((index & yBits) == index && IsSatisfiesRule(index | xBits, yBits))
		{
			simplexBits = index | xBits;
			closestPoint = ComputeClosestPoint();
			
			return true;
		}
	}
	
	bool flag = false;
	if(IsSatisfiesRule(xBits, yBits))
	{
		simplexBits = xBits;
		closestPoint = y[newIndex];
		maxLengthSq = yLengthSq[newIndex];
		flag = true;
	}

	return flag;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 가까운 위치 계산
///@return 결과 위치벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Gjk::ComputeClosestPoint()
{
	float num1 = 0.0f;
	int num2 = BitsToIndices[simplexBits];
	Vector3 zero = Vector3::Zero;
	maxLengthSq = 0.0f;
	
	while (num2 != 0)
	{
		int index = (num2 & 7) - 1;
		float num3 = det[simplexBits][index];
		num1 += num3;
		zero += y[index] * num3;
		maxLengthSq = MathHelper::Max(maxLengthSq, yLengthSq[index]);
		num2 >>= 3;
	}
	return zero / num1;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief Bits값이 규칙에 맞는지 검사
///@param xBits : XBits
///@param yBits : YBits
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool Gjk::IsSatisfiesRule( int xBits, int yBits )
{
	bool flag = true;
	int num1 = BitsToIndices[yBits];

	while(num1 != 0)
	{
		int index = (num1 & 7) - 1;
		int num2 = 1 << index;
		
		if((num2 & xBits) != 0)
		{
			if((double)det[xBits][index] <= 0.0)
			{
				flag = false;
				break;
			}
		}
		else if((double)det[xBits | num2][index] > 0.0)
		{
			flag = false;
			break;
		}

		num1 >>= 3;
	}

	return flag;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 두 개의 벡터 내적
///@param a : 벡터1
///@param b : 벡터2
///@return 결과 값
//////////////////////////////////////////////////////////////////////////
float Gjk::Dot( Vector3 a, Vector3 b )
{
	return (float)((double)a.X * (double)b.X + (double)a.Y * (double)b.Y + (double)a.Z * (double)b.Z);
}<file_sep>#include "stdafx.h"
#include "ExportAnim.h"
#include "./Fbx/XmlToAnim.h"

ExportAnim::ExportAnim(ExecuteValues* values)
	: Execute(values)
{
	Fbx::XmlToAnim* anim = NULL;

	vector<wstring> list;
	Path::GetFiles(&list, Assets + L"Bone/Players/Grund/", L"*.Animation", false);

	for (wstring file : list)
	{
		wstring name = Path::GetFileNameWithoutExtension(file);

		anim = new Fbx::XmlToAnim(file);
		anim->ExportAnimation(Models + L"Grund/", name);
		SAFE_DELETE(anim);
	}
}

ExportAnim::~ExportAnim()
{
	
}

void ExportAnim::Update()
{
	
}

void ExportAnim::Render()
{
	
}

void ExportAnim::PostRender()
{

}
<file_sep>#include "Quaternion.h"

#include <d3dx9math.h>
#include "Vector3.h"
#include "Matrix.h"

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

const Quaternion Quaternion::Identity = Quaternion(0.0f, 0.0f, 0.0f, 1.0f);

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


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
//////////////////////////////////////////////////////////////////////////
Quaternion::Quaternion( void )
{
	this->X = 0.0f;
	this->Y = 0.0f;
	this->Z = 0.0f;
	this->W = 0.0f;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
///@param x : X
///@param y : Y
///@param z : Z
///@param w : W
//////////////////////////////////////////////////////////////////////////
Quaternion::Quaternion( float x, float y, float z, float w )
{
	this->X = x;
	this->Y = y;
	this->Z = z;
	this->W = w;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
///@param vectorPart : 벡터(XYZ)
///@param scalarPart : 값(W)
//////////////////////////////////////////////////////////////////////////
Quaternion::Quaternion( Vector3 vectorPart, float scalarPart )
{
	this->X = vectorPart.X;
	this->Y = vectorPart.Y;
	this->Z = vectorPart.Z;
	this->W = scalarPart;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief -
///@return 결과 쿼터니온
//////////////////////////////////////////////////////////////////////////
Quaternion Quaternion::operator-( void )
{
	Quaternion quaternion1;
	quaternion1.X = -this->X;
	quaternion1.Y = -this->Y;
	quaternion1.Z = -this->Z;
	quaternion1.W = -this->W;

	return quaternion1;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief ==
///@param quaternion2 : 쿼터니온
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool Quaternion::operator==( const Quaternion& quaternion2 ) const
{
	if((double)X == (double)quaternion2.X && (double)Y == (double)quaternion2.Y && (double)Z == (double)quaternion2.Z)
		return (double)W == (double)quaternion2.W;
	else
		return false;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief !=
///@param quaternion2 : 쿼터니온
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool Quaternion::operator!=( const Quaternion& quaternion2 ) const
{
	if((double)X == (double)quaternion2.X && (double)Y == (double)quaternion2.Y && (double)Z == (double)quaternion2.Z)
		return (double)W != (double)quaternion2.W;
	else
		return true;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief +
///@param quaternion2 : 쿼터니온
///@return 결과
//////////////////////////////////////////////////////////////////////////
Quaternion Quaternion::operator+( const Quaternion& quaternion2 ) const
{
	Quaternion quaternion;
	quaternion.X = this->X + quaternion2.X;
	quaternion.Y = this->Y + quaternion2.Y;
	quaternion.Z = this->Z + quaternion2.Z;
	quaternion.W = this->W + quaternion2.W;

	return quaternion;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief -
///@param quaternion2 : 쿼터니온
///@return 결과
//////////////////////////////////////////////////////////////////////////
Quaternion Quaternion::operator-( const Quaternion& quaternion2 ) const
{
	Quaternion quaternion;
	quaternion.X = this->X - quaternion2.X;
	quaternion.Y = this->Y - quaternion2.Y;
	quaternion.Z = this->Z - quaternion2.Z;
	quaternion.W = this->W - quaternion2.W;
	return quaternion;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief *
///@param quaternion2 : 쿼터니온
///@return 결과
//////////////////////////////////////////////////////////////////////////
Quaternion Quaternion::operator*( const Quaternion& quaternion2 ) const
{
	float num1 = (float)((double)this->Y * (double)quaternion2.Z - (double)this->Z * (double)quaternion2.Y);
	float num2 = (float)((double)this->Z * (double)quaternion2.X - (double)this->X * (double)quaternion2.Z);
	float num3 = (float)((double)this->X * (double)quaternion2.Y - (double)this->Y * (double)quaternion2.X);
	float num4 = (float)((double)this->X * (double)quaternion2.X + (double)this->Y * (double)quaternion2.Y + (double)this->Z * (double)quaternion2.Z);

	Quaternion quaternion;
	quaternion.X = (float)((double)this->X * (double)quaternion2.W + (double)quaternion2.X * (double)this->W) + num1;
	quaternion.Y = (float)((double)this->Y * (double)quaternion2.W + (double)quaternion2.Y * (double)this->W) + num2;
	quaternion.Z = (float)((double)this->Z * (double)quaternion2.W + (double)quaternion2.Z * (double)this->W) + num3;
	quaternion.W = this->W * quaternion2.W - num4;

	return quaternion;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief *
///@param scaleFactor : 값
///@return 결과
//////////////////////////////////////////////////////////////////////////
Quaternion Quaternion::operator*( const float& scaleFactor ) const
{
	Quaternion quaternion;
	quaternion.X = this->X * scaleFactor;
	quaternion.Y = this->Y * scaleFactor;
	quaternion.Z = this->Z * scaleFactor;
	quaternion.W = this->W * scaleFactor;

	return quaternion;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief *
///@param quaternion2 : 쿼터니온
///@return 결과
//////////////////////////////////////////////////////////////////////////
Quaternion Quaternion::operator/( const Quaternion& quaternion2 ) const
{
	float num1 = 1.0f / (float)((double)quaternion2.X * (double)quaternion2.X + (double)quaternion2.Y * (double)quaternion2.Y + (double)quaternion2.Z * (double)quaternion2.Z + (double)quaternion2.W * (double)quaternion2.W);
	float num2 = -quaternion2.X * num1;
	float num3 = -quaternion2.Y * num1;
	float num4 = -quaternion2.Z * num1;
	float num5 = quaternion2.W * num1;

	float multiple1 = (float)((double)this->Y * (double)num4 - (double)this->Z * (double)num3);
	float multiple2 = (float)((double)this->Z * (double)num2 - (double)this->X * (double)num4);
	float multiple3 = (float)((double)this->X * (double)num3 - (double)this->Y * (double)num2);
	float multiple4 = (float)((double)this->X * (double)num2 + (double)this->Y * (double)num3 + (double)this->Z * (double)num4);

	Quaternion quaternion;
	quaternion.X = (float)((double)this->X * (double)num5 + (double)num2 * (double)this->W) + multiple1;
	quaternion.Y = (float)((double)this->Y * (double)num5 + (double)num3 * (double)this->W) + multiple2;
	quaternion.Z = (float)((double)this->Z * (double)num5 + (double)num4 * (double)this->W) + multiple3;
	quaternion.W = this->W * num5 - multiple4;
	
	return quaternion;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief +=
///@param quaternion2 : 쿼터니온
///@return 결과
//////////////////////////////////////////////////////////////////////////
void Quaternion::operator+=( const Quaternion& quaternion2 )
{
	*this = *this + quaternion2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief -=
///@param quaternion2 : 쿼터니온
///@return 결과
//////////////////////////////////////////////////////////////////////////
void Quaternion::operator-=( const Quaternion& quaternion2 )
{
	*this = *this - quaternion2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief *=
///@param quaternion2 : 쿼터니온
///@return 결과
//////////////////////////////////////////////////////////////////////////
void Quaternion::operator*=( const Quaternion& quaternion2 )
{
	*this = *this * quaternion2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief *=
///@param scaleFactor : 값
///@return 결과
//////////////////////////////////////////////////////////////////////////
void Quaternion::operator*=( const float& scaleFactor )
{
	*this = *this * scaleFactor;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief /=
///@param quaternion2 : 쿼터니온
///@return 결과
//////////////////////////////////////////////////////////////////////////
void Quaternion::operator/=( const Quaternion& quaternion2 )
{
	*this = *this / quaternion2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 문자열로 변환
///@param 문자열
//////////////////////////////////////////////////////////////////////////
std::string Quaternion::ToString()
{
	std::string temp;
	char val[255];

	sprintf(val, "{X:%#f ", X); temp += val; 
	sprintf(val, "Y:%#f ", Y); temp += val;
	sprintf(val, "Z:%#f ", Z); temp += val;
	sprintf(val, "W:%#f}", W); temp += val;

	return temp;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief D3DXQUATERNION으로 변환
///@param D3DX 쿼터니온
//////////////////////////////////////////////////////////////////////////
D3DXQUATERNION Quaternion::ToD3DXQUATERNION()
{
	return D3DXQUATERNION(X, Y, Z, W);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 크기 계산
///@return 결과 값
//////////////////////////////////////////////////////////////////////////
float Quaternion::Length()
{
	return (float)sqrt((double)X * (double)X + (double)Y * (double)Y + (double)Z * (double)Z + (double)W * (double)W);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 제곱으로 크기 계산
///@return 결과 값
//////////////////////////////////////////////////////////////////////////
float Quaternion::LengthSquared()
{
	return (float)((double)X * (double)X + (double)Y * (double)Y + (double)Z * (double)Z + (double)W * (double)W);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 정규화
//////////////////////////////////////////////////////////////////////////
void Quaternion::Normalize()
{
	float num = 1.0f / (float)sqrt((double)X * (double)X + (double)Y * (double)Y + (double)Z * (double)Z + (double)W * (double)W);
	
	X *= num;
	Y *= num;
	Z *= num;
	W *= num;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 정규화
///@param value : 쿼터니온
///@return 결과 쿼터니온
//////////////////////////////////////////////////////////////////////////
Quaternion Quaternion::Normalize( Quaternion quaternion )
{
	float num = 1.0f / (float)sqrt((double)quaternion.X * (double)quaternion.X + (double)quaternion.Y * (double)quaternion.Y + (double)quaternion.Z * (double)quaternion.Z + (double)quaternion.W * (double)quaternion.W);

	Quaternion quaternion1;
	quaternion1.X = quaternion.X * num;
	quaternion1.Y = quaternion.Y * num;
	quaternion1.Z = quaternion.Z * num;
	quaternion1.W = quaternion.W * num;

	return quaternion1;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 쿼터니온 켤레값
//////////////////////////////////////////////////////////////////////////
void Quaternion::Conjugate()
{
	this->X = -this->X;
	this->Y = -this->Y;
	this->Z = -this->Z;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 쿼터니온 켤레값
///@param value : 쿼터니온
///@return 결과 쿼터니온
//////////////////////////////////////////////////////////////////////////
Quaternion Quaternion::Conjugate( Quaternion value )
{
	Quaternion quaternion;
	quaternion.X = -value.X;
	quaternion.Y = -value.Y;
	quaternion.Z = -value.Z;
	quaternion.W = value.W;
	
	return quaternion;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 역 쿼터니온
///@param quaternion : 쿼터니온
///@return 결과 쿼터니온
//////////////////////////////////////////////////////////////////////////
Quaternion Quaternion::Inverse( Quaternion quaternion )
{
	float num = 1.0f / (float)((double)quaternion.X * (double)quaternion.X + (double)quaternion.Y * (double)quaternion.Y + (double)quaternion.Z * (double)quaternion.Z + (double)quaternion.W * (double)quaternion.W);

	Quaternion quaternion1;
	quaternion1.X = -quaternion.X * num;
	quaternion1.Y = -quaternion.Y * num;
	quaternion1.Z = -quaternion.Z * num;
	quaternion1.W = quaternion.W * num;
	
	return quaternion1;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 축과 각도에 의해 회전된 쿼터니온
///@param axis : 축 벡터
///@param angle : 각도
///@return 결과 쿼터니온
//////////////////////////////////////////////////////////////////////////
Quaternion Quaternion::CreateFromAxisAngle( Vector3 axis, float angle )
{
	float sinValue = (float)sin((double)(angle * 0.5f));
	float cosValue = (float)cos((double)(angle * 0.5f));

	Quaternion quaternion;
	quaternion.X = axis.X * sinValue;
	quaternion.Y = axis.Y * sinValue;
	quaternion.Z = axis.Z * sinValue;
	quaternion.W = cosValue;

	return quaternion;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 각 각도에 의해 회전된 쿼터니온
///@param yaw : Yaw
///@param pitch : Pitch
///@param roll : Roll
//////////////////////////////////////////////////////////////////////////
Quaternion Quaternion::CreateFromYawPitchRoll( float yaw, float pitch, float roll )
{
	float roll1 = roll * 0.5f;
	float roll2 = (float)sin((double)roll1);
	float roll3 = (float)cos((double)roll1);

	float pitch1 = pitch * 0.5f;
	float pitch2 = (float)sin((double)pitch1);
	float pitch3 = (float)cos((double)pitch1);

	float yaw1 = yaw * 0.5f;
	float yaw2 = (float)sin((double)yaw1);
	float yaw3 = (float)cos((double)yaw1);
	
	Quaternion quaternion;
	quaternion.X = (float)((double)yaw3 * (double)pitch2 * (double)roll3 + (double)yaw2 * (double)pitch3 * (double)roll2);
	quaternion.Y = (float)((double)yaw2 * (double)pitch3 * (double)roll3 - (double)yaw3 * (double)pitch2 * (double)roll2);
	quaternion.Z = (float)((double)yaw3 * (double)pitch3 * (double)roll2 - (double)yaw2 * (double)pitch2 * (double)roll3);
	quaternion.W = (float)((double)yaw3 * (double)pitch3 * (double)roll3 + (double)yaw2 * (double)pitch2 * (double)roll2);

	return quaternion;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 매트릭스에 의해 회전된 쿼터니온
///@param matrix : 매트릭스
///@return 결과 쿼터니온
//////////////////////////////////////////////////////////////////////////
Quaternion Quaternion::CreateFromRotationMatrix( Matrix matrix )
{
	float num1 = matrix.M11 + matrix.M22 + matrix.M33;

	Quaternion quaternion;
	if((double)num1 > 0.0)
	{
		float num2 = (float)sqrt((double)num1 + 1.0);
		quaternion.W = num2 * 0.5f;

		float num3 = 0.5f / num2;
		quaternion.X = (matrix.M23 - matrix.M32)* num3;
		quaternion.Y = (matrix.M31 - matrix.M13)* num3;
		quaternion.Z = (matrix.M12 - matrix.M21)* num3;
	}
	else if((double)matrix.M11 >= (double)matrix.M22 && (double)matrix.M11 >= (double)matrix.M33)
	{
		float num2 = (float)sqrt(1.0 + (double)matrix.M11 - (double)matrix.M22 - (double)matrix.M33);

		float num3 = 0.5f / num2;
		quaternion.X = 0.5f * num2;
		quaternion.Y = (matrix.M12 + matrix.M21)* num3;
		quaternion.Z = (matrix.M13 + matrix.M31)* num3;
		quaternion.W = (matrix.M23 - matrix.M32)* num3;
	}
	else if((double)matrix.M22 > (double)matrix.M33)
	{
		float num2 = (float)sqrt(1.0 + (double)matrix.M22 - (double)matrix.M11 - (double)matrix.M33);

		float num3 = 0.5f / num2;
		quaternion.X = (matrix.M21 + matrix.M12)* num3;
		quaternion.Y = 0.5f * num2;
		quaternion.Z = (matrix.M32 + matrix.M23)* num3;
		quaternion.W = (matrix.M31 - matrix.M13)* num3;
	}
	else
	{
		float num2 = (float)sqrt(1.0 + (double)matrix.M33 - (double)matrix.M11 - (double)matrix.M22);

		float num3 = 0.5f / num2;
		quaternion.X = (matrix.M31 + matrix.M13)* num3;
		quaternion.Y = (matrix.M32 + matrix.M23)* num3;
		quaternion.Z = 0.5f * num2;
		quaternion.W = (matrix.M12 - matrix.M21)* num3;
	}

	return quaternion;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 내적
///@param quaternion1 : 쿼터니온1
///@param quaternion2 : 쿼터니온2
///@return 결과 쿼터니온
//////////////////////////////////////////////////////////////////////////
float Quaternion::Dot( Quaternion quaternion1, Quaternion quaternion2 )
{
	return (float)((double)quaternion1.X * (double)quaternion2.X + (double)quaternion1.Y * (double)quaternion2.Y + (double)quaternion1.Z * (double)quaternion2.Z + (double)quaternion1.W * (double)quaternion2.W);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 구면보간
///@param quaternion1 : 쿼터니온1
///@param quaternion2 : 쿼터니온2
///@param amount : 보간값
///@return 결과 쿼터니온
//////////////////////////////////////////////////////////////////////////
Quaternion Quaternion::Slerp( Quaternion quaternion1, Quaternion quaternion2, float amount )
{
	float normal = (float)((double)quaternion1.X * (double)quaternion2.X + (double)quaternion1.Y * (double)quaternion2.Y + (double)quaternion1.Z * (double)quaternion2.Z + (double)quaternion1.W * (double)quaternion2.W);

	bool flag = false;
	if((double)normal < 0.0)
	{
		flag = true;
		normal = -normal;
	}

	float num1, num2;
	if((double)normal > 0.999998986721039)
	{
		num1 = 1.0f - amount;
		num2 = flag ? -amount : amount;
	}
	else
	{
		float num3 = (float)acos((double)normal);
		float num4 = (float)(1.0 / sin((double)num3));

		num1 = (float)sin((1.0 - (double)amount)* (double)num3)* num4;
		num2 = flag ? (float)-sin((double)amount * (double)num3)* num4 : (float)sin((double)amount * (double)num3)* num4;
	}
	Quaternion quaternion;
	quaternion.X = (float)((double)num1 * (double)quaternion1.X + (double)num2 * (double)quaternion2.X);
	quaternion.Y = (float)((double)num1 * (double)quaternion1.Y + (double)num2 * (double)quaternion2.Y);
	quaternion.Z = (float)((double)num1 * (double)quaternion1.Z + (double)num2 * (double)quaternion2.Z);
	quaternion.W = (float)((double)num1 * (double)quaternion1.W + (double)num2 * (double)quaternion2.W);

	return quaternion;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 선형보간
///@param quaternion1 : 쿼터니온1
///@param quaternion2 : 쿼터니온2
///@param amount : 보간값
///@return 결과 쿼터니온
//////////////////////////////////////////////////////////////////////////
Quaternion Quaternion::Lerp( Quaternion quaternion1, Quaternion quaternion2, float amount )
{
	float amountInv = 1.0f - amount;
	Quaternion quaternion;

	if((double)quaternion1.X * (double)quaternion2.X + (double)quaternion1.Y * (double)quaternion2.Y + (double)quaternion1.Z * (double)quaternion2.Z + (double)quaternion1.W * (double)quaternion2.W >= 0.0)
	{
		quaternion.X = (float)((double)amountInv * (double)quaternion1.X + (double)amount * (double)quaternion2.X);
		quaternion.Y = (float)((double)amountInv * (double)quaternion1.Y + (double)amount * (double)quaternion2.Y);
		quaternion.Z = (float)((double)amountInv * (double)quaternion1.Z + (double)amount * (double)quaternion2.Z);
		quaternion.W = (float)((double)amountInv * (double)quaternion1.W + (double)amount * (double)quaternion2.W);
	}
	else
	{
		quaternion.X = (float)((double)amountInv * (double)quaternion1.X - (double)amount * (double)quaternion2.X);
		quaternion.Y = (float)((double)amountInv * (double)quaternion1.Y - (double)amount * (double)quaternion2.Y);
		quaternion.Z = (float)((double)amountInv * (double)quaternion1.Z - (double)amount * (double)quaternion2.Z);
		quaternion.W = (float)((double)amountInv * (double)quaternion1.W - (double)amount * (double)quaternion2.W);
	}
	
	float length = 1.0f / (float)sqrt((double)quaternion.X * (double)quaternion.X + (double)quaternion.Y * (double)quaternion.Y + (double)quaternion.Z * (double)quaternion.Z + (double)quaternion.W * (double)quaternion.W);
	quaternion.X *= length;
	quaternion.Y *= length;
	quaternion.Z *= length;
	quaternion.W *= length;

	return quaternion;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 순서를 바꾸어 곱하기
///@param value1 : 쿼터니온1
///@param value2 : 쿼터니온2
///@return 결과 쿼터니온
//////////////////////////////////////////////////////////////////////////
Quaternion Quaternion::Concatenate( Quaternion value1, Quaternion value2 )
{
	float num1 = (float)((double)value2.Y * (double)value1.Z - (double)value2.Z * (double)value1.Y);
	float num2 = (float)((double)value2.Z * (double)value1.X - (double)value2.X * (double)value1.Z);
	float num3 = (float)((double)value2.X * (double)value1.Y - (double)value2.Y * (double)value1.X);
	float num4 = (float)((double)value2.X * (double)value1.X + (double)value2.Y * (double)value1.Y + (double)value2.Z * (double)value1.Z);

	Quaternion quaternion;
	quaternion.X = (float)((double)value2.X * (double)value1.W + (double)value1.X * (double)value2.W)+ num1;
	quaternion.Y = (float)((double)value2.Y * (double)value1.W + (double)value1.Y * (double)value2.W)+ num2;
	quaternion.Z = (float)((double)value2.Z * (double)value1.W + (double)value1.Z * (double)value2.W)+ num3;
	quaternion.W = value2.W * value1.W - num4;

	return quaternion;
}<file_sep>#pragma once

#include "../Core/Vector3.h"

class BoundingBox;
class BoundingFrustum;
class BoundingSphere;
class Plane;

//////////////////////////////////////////////////////////////////////////
///@brief 충돌 레이
//////////////////////////////////////////////////////////////////////////
class Ray
{
public:
	Ray(void);
	Ray(Vector3 position, Vector3 direction);

	bool operator ==(const Ray& value) const;
	bool operator !=(const Ray& value) const;

	std::string ToString();

	bool Intersects(Plane& plane, float& value);
	bool Intersects(BoundingSphere& sphere, float& value);

public:
	Vector3 Position;///< 위치
	Vector3 Direction;///< 방향
};<file_sep>#pragma once
#include "./Framework/Bounding/BoundingBox.h"
#include "./Framework/Bounding/BoundingSphere.h"

namespace Gizmo
{
	class Gizmo;

	enum class EGizmoMode
	{
		Scale = 0, Rotate, Translate
	};

	enum class EGizmoAxis
	{
		None = -1, X, Y, Z,
		XY, ZX, YZ,
	};

	class GizmoComponent
	{
	public:
		GizmoComponent(ExecuteValues* values);
		~GizmoComponent();

		void Update();
		void Render();
		void PostRender();

		void Position(const D3DXVECTOR3& value) { position = value; }
		void SetTarget(D3DXMATRIX* target) { this->target = target; }
		void Transform(D3DXMATRIX& val) { gizmoWorld = val; }
		void OutsideWorld(D3DXMATRIX& val) { outsideWorld = val; }
		D3DXMATRIX TransformDelta();
	private:
		//Initialize
		void Init();

		//Draw
		void Draw2D();
		void Draw3D();
		void DrawBounding();

		//Create
		void Create2D();
		void Create3D();
		void CreateBoundings();

		//Reset
		void ResetHighlight();
		void ResetMouseValues();
		void ResetDeltas();
		void ResetScaleGizmo();

		//Mouse
		void MouseCollision();
		void Pressing();
		Ray ConvertMouseToRay(D3DXMATRIX& world);

		//ResizeWorldScale
		void ResizeWorldScale();
	private:
		//Gizmos
		D3DXMATRIX geometryWorld[3];
		D3DXCOLOR colors[3];
		vector<Gizmo *> quads;
		vector<Gizmo *> lines;
		vector<Gizmo *> scales, rotates, translates;
		vector<Gizmo *> boxes;
		vector<Gizmo *> spheres;

		//Boundings		
		class BoundingBox* xAxisBox, *yAxisBox, *zAxisBox;
		class BoundingBox* xyAxisBox, *yzAxisBox, *xzAxisBox;
		class BoundingSphere* xSphere, *ySphere, *zSphere;
		bool bDrawBounding;

		//Line
		const float LINE_LENGTH = 3.0f;
		const float LINE_OFFSET = 1.0f;

		//Enum
		EGizmoMode activeMode;
		EGizmoAxis activeAxis;

		//MousePos
		Vector3 intersectPosition, lastIntersectPosition, delta;
		D3DXVECTOR3 curMousePos, lastMousePos;
		bool bMousePressed;

		//Transform
		D3DXMATRIX outsideWorld;
		D3DXMATRIX gizmoWorld;
		D3DXVECTOR3 scale, rotate, position;
		D3DXMATRIX scaleMat, rotMat, posMat;
		D3DXQUATERNION rotQuat;
		const float ROTATE_WEIGHT = 10.0f;
		const float SCALE_WEIGHT = 0.1f;
		const float RESIZE_RATIO = 30.0f;

		//Deltas
		D3DXVECTOR3 translationDelta, scaleDelta;
		D3DXMATRIX rotationDelta;

		//States
		ID3D11RasterizerState* rasterizer[2];
		ID3D11DepthStencilState* depthStencilState[2];

		//GlobalValue
		ExecuteValues* values;

		//Target
		D3DXMATRIX* target;
	};
}<file_sep>#include "BoundingFrustum.h"

#include <assert.h>
#include "Bounding.h"
#include "Ray.h"
#include "BoundingBox.h"
#include "BoundingSphere.h"

#include "../Core/MathHelper.h"

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

const int BoundingFrustum::CornerCount = 8;
const int BoundingFrustum::NearPlaneIndex = 0;
const int BoundingFrustum::FarPlaneIndex = 1;
const int BoundingFrustum::LeftPlaneIndex = 2;
const int BoundingFrustum::RightPlaneIndex = 3;
const int BoundingFrustum::TopPlaneIndex = 4;
const int BoundingFrustum::BottomPlaneIndex = 5;
const int BoundingFrustum::NumPlanes = 6;

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


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
//////////////////////////////////////////////////////////////////////////
BoundingFrustum::BoundingFrustum( void )
{

}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
///@param value : 매트릭스
//////////////////////////////////////////////////////////////////////////
BoundingFrustum::BoundingFrustum( Matrix value )
{
	SetMatrix(value);
}

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


//////////////////////////////////////////////////////////////////////////
///@brief ==
///@param value : 바운딩 프러스텀
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool BoundingFrustum::operator==( const BoundingFrustum& value ) const
{
	return Equals(value);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief ==
///@param value : 바운딩 프러스텀
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool BoundingFrustum::operator!=( const BoundingFrustum& value ) const
{
	return !Equals(value);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 문자열로 변환
///@param 문자열
//////////////////////////////////////////////////////////////////////////
std::string BoundingFrustum::ToString()
{
	std::string temp;

	temp += "{{Near:" + planes[0].ToString() + "}, ";
	temp += "{Far:" + planes[1].ToString() + "}, ";
	temp += "{Left:" + planes[2].ToString() + "}, ";
	temp += "{Right:" + planes[3].ToString() + "}, ";
	temp += "{Top:" + planes[4].ToString() + "}, ";
	temp += "{Bottom:" + planes[5].ToString() + "}}";

	return temp;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 서포트 매핑
///@param v : 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 BoundingFrustum::SupportMapping( Vector3 v )
{
	float result1;
	int index1 = 0;
	result1 = Vector3::Dot(cornerArray[0], v);

	for(int index2 = 1; index2 < 8; ++index2)
	{
		float result2;
		result2 = Vector3::Dot(cornerArray[index2], v);

		if((double)result2 > (double)result1)
		{
			index1 = index2;
			result1 = result2;
		}
	}

	return cornerArray[index1];
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 값이 같은 객체인지 검사
///@param value : <NAME>텀
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool BoundingFrustum::Equals( const BoundingFrustum& value ) const
{
	bool flag = false;
	flag = matrix == value.matrix;

	return flag;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 근면
///@return 결과 면
//////////////////////////////////////////////////////////////////////////
Plane BoundingFrustum::Near() const
{
	return planes[0];
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 원면
///@return 결과 면
//////////////////////////////////////////////////////////////////////////
Plane BoundingFrustum::Far() const
{
	return planes[1];
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 좌측면
///@return 결과 면
//////////////////////////////////////////////////////////////////////////
Plane BoundingFrustum::Left() const
{
	return planes[2];
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 우측면
///@return 결과 면
//////////////////////////////////////////////////////////////////////////
Plane BoundingFrustum::Right() const
{
	return planes[3];
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 윗면
///@return 결과 면
//////////////////////////////////////////////////////////////////////////
Plane BoundingFrustum::Top() const
{
	return planes[4];
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 아랫면
///@return 결과 면
//////////////////////////////////////////////////////////////////////////
Plane BoundingFrustum::Bottom() const
{
	return planes[5];
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 매트릭스
///@return 결과 매트릭스
//////////////////////////////////////////////////////////////////////////
Matrix BoundingFrustum::GetMatrix() const
{
	return matrix;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 매트릭스 세팅
///@param value : 설정할 매트릭스
//////////////////////////////////////////////////////////////////////////
void BoundingFrustum::SetMatrix( const Matrix value )
{
	matrix = value;
	planes[2].Normal.X = -value.M14 - value.M11; planes[2].Normal.Y = -value.M24 - value.M21; planes[2].Normal.Z = -value.M34 - value.M31; planes[2].D = -value.M44 - value.M41;
	planes[3].Normal.X = -value.M14 + value.M11; planes[3].Normal.Y = -value.M24 + value.M21; planes[3].Normal.Z = -value.M34 + value.M31; planes[3].D = -value.M44 + value.M41;
	planes[4].Normal.X = -value.M14 + value.M12; planes[4].Normal.Y = -value.M24 + value.M22; planes[4].Normal.Z = -value.M34 + value.M32; planes[4].D = -value.M44 + value.M42;
	planes[5].Normal.X = -value.M14 - value.M12; planes[5].Normal.Y = -value.M24 - value.M22; planes[5].Normal.Z = -value.M34 - value.M32; planes[5].D = -value.M44 - value.M42;

	planes[0].Normal.X = -value.M13;
	planes[0].Normal.Y = -value.M23;
	planes[0].Normal.Z = -value.M33;
	planes[0].D = -value.M43;

	planes[1].Normal.X = -value.M14 + value.M13;
	planes[1].Normal.Y = -value.M24 + value.M23;
	planes[1].Normal.Z = -value.M34 + value.M33;
	planes[1].D = -value.M44 + value.M43;

	for(int index = 0; index < 6; ++index)
	{
		float num = planes[index].Normal.Length();
		planes[index].Normal /= num;
		planes[index].D /= num;
	}

	Ray intersectionLine1 = ComputeIntersectionLine(planes[0], planes[2]);
	cornerArray[0] = ComputeIntersection(planes[4], intersectionLine1);
	cornerArray[3] = ComputeIntersection(planes[5], intersectionLine1);

	Ray intersectionLine2 = ComputeIntersectionLine(planes[3], planes[0]);
	cornerArray[1] = ComputeIntersection(planes[4], intersectionLine2);
	cornerArray[2] = ComputeIntersection(planes[5], intersectionLine2);

	intersectionLine2 = ComputeIntersectionLine(planes[2], planes[1]);
	cornerArray[4] = ComputeIntersection(planes[4], intersectionLine2);
	cornerArray[7] = ComputeIntersection(planes[5], intersectionLine2);

	intersectionLine2 = ComputeIntersectionLine(planes[1], planes[3]);
	cornerArray[5] = ComputeIntersection(planes[4], intersectionLine2);
	cornerArray[6] = ComputeIntersection(planes[5], intersectionLine2);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 코너 얻기
///@param pOut : 
//////////////////////////////////////////////////////////////////////////
void BoundingFrustum::GetCorner( Vector3* pCorner )
{
	assert(pCorner != NULL);

	for(int i = 0; i < 8; i++)
		pCorner[i] = cornerArray[i];
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 면 두개의 교차선 계산
///@return 결과 교차선
//////////////////////////////////////////////////////////////////////////
Ray BoundingFrustum::ComputeIntersectionLine( Plane p1, Plane p2 )
{
	Ray ray;
	ray.Direction = Vector3::Cross(p1.Normal, p2.Normal);
	
	float num = ray.Direction.LengthSquared();
	ray.Position = Vector3::Cross(-p1.D * p2.Normal + p2.D * p1.Normal, ray.Direction) / num;
	
	return ray;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 면과 레이의 교차 위치 계산
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 BoundingFrustum::ComputeIntersection( Plane plane, Ray ray )
{
	float num = (-plane.D - Vector3::Dot(plane.Normal, ray.Position)) / Vector3::Dot(plane.Normal, ray.Direction);
	
	return ray.Position + ray.Direction * num;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 박스와 교차 검사
///@param box : 바운딩 박스
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool BoundingFrustum::Intersects( BoundingBox box )
{	
	bool result = false;
	Intersects(box, result);
	
	return result;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 박스와 교차 검사
///@param box : 바운딩 박스
///@param result : 결과
//////////////////////////////////////////////////////////////////////////
void BoundingFrustum::Intersects( BoundingBox box, bool& result )
{
	gjk.Reset();
	
	Vector3 result1;
	result1 = cornerArray[0] - box.Min;
	
	if((double)result1.LengthSquared() < 9.99999974737875E-06)
		result1 = cornerArray[0] - box.Max;

	float num1 = MathHelper::FloatMaxValue;
	float num2;
	result = false;

	do
	{
		Vector3 v(-result1.X, -result1.Y, -result1.Z);

		Vector3 result2 = SupportMapping(v);
		Vector3 result3 = box.SupportMapping(result1);
		Vector3 result4 = result2 - result3;
		if((double)result1.X * (double)result4.X + (double)result1.Y * (double)result4.Y + (double)result1.Z * (double)result4.Z > 0.0)
		{
			return;
		}
		else
		{
			gjk.AddSupportPoint(result4);
			result1 = gjk.ClosestPoint();
			
			float num3 = num1;
			num1 = result1.LengthSquared();

			if ((double) num3 - (double)num1 <= 9.99999974737875E-06 * (double)num3)
				return;
			else
				num2 = 4E-05f * gjk.MaxLengthSquared();
		}
	}
	while(!gjk.FullSimplex() && (double)num1 >= (double)num2);

	result = true;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 프러스텀과 교차 검사
///@param frustum : 바운딩 프러스텀
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool BoundingFrustum::Intersects( BoundingFrustum frustum )
{
	gjk.Reset();
	Vector3 result1;
	result1 = cornerArray[0] - frustum.cornerArray[0];
	
	if((double) result1.LengthSquared() < 9.99999974737875E-06)
		result1 = cornerArray[0] - frustum.cornerArray[1];

	float num1 = MathHelper::FloatMaxValue;
	float num2;
	do
	{
		Vector3 v(-result1.X, -result1.Y, -result1.Z);
		Vector3 result2 = SupportMapping(v);
		Vector3 result3 = frustum.SupportMapping(result1);
		Vector3 result4 = result2 - result3;
		
		if((double)result1.X * (double)result4.X + (double)result1.Y * (double)result4.Y + (double)result1.Z * (double)result4.Z > 0.0)
		{
			return false;
		}
		else
		{
			gjk.AddSupportPoint(result4);
			result1 = gjk.ClosestPoint();

			float num3 = num1;
			num1 = result1.LengthSquared();
			num2 = 4E-05f * gjk.MaxLengthSquared();

			if((double)num3 - (double)num1 <= 9.99999974737875E-06 * (double)num3)
				return false;
		}
	}
	while(!gjk.FullSimplex() && (double)num1 >= (double)num2);

	return true;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 면과 교차 검사
///@param plane : 면
///@return 결과
//////////////////////////////////////////////////////////////////////////
void BoundingFrustum::Intersects( Plane plane, PlaneIntersectionType& result )
{
	int num = 0;
	for(int index = 0; index < 8; ++index)
	{
		float result = Vector3::Dot(cornerArray[index], plane.Normal);

		if((double)result + (double)plane.D > 0.0)
			num |= 1;
		else
			num |= 2;
		
		if(num == 3)
		{
			result = PlaneIntersectionType_Intersecting;
			
			return ;
		}
	}
	
	result = num == 1 ? PlaneIntersectionType_Front : PlaneIntersectionType_Back;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 레이와의 교차검사
///@param ray : 레이
///@param result : 교차 결과값
///@warning
///		교차가 되지 않은 결과 result는 0.0f이 절대 아니다!
///		result == NULL 이다!!!!!
//////////////////////////////////////////////////////////////////////////
void BoundingFrustum::Intersects( Ray ray, float* result )
{
	ContainmentType result1;
	result1 = Contains(ray.Position);
	if (result1 == ContainmentType_Contains)
	{
		*result = 0.0f;
	}
	else
	{
		float num1 = MathHelper::FloatMinValue;
		float num2 = MathHelper::FloatMaxValue;

		if(result != NULL)
		{
			delete result;
			result = NULL;
		}
		result = new float();
		
		for(int i = 0; i < 6; i++)
		{
			Plane plane = planes[i];

			Vector3 vector2 = plane.Normal;
			float result2 = Vector3::Dot(ray.Direction, vector2);
			float result3 = Vector3::Dot(ray.Position, vector2);
			result3 += plane.D;
			
			if((double)MathHelper::Abs(result2) < 9.99999974737875E-06)
			{
				if ((double)result3 > 0.0)
					return;
			}
			else
			{
				float num3 = -result3 / result2;

				if((double)result2 < 0.0)
				{
					if((double) num3 > (double)num2)
						return;
					else if((double)num3 > (double)num1)
						num1 = num3;
				}
				else if((double)num3 < (double)num1)
					return;
				else if((double)num3 < (double)num2)
					num2 = num3;
			}
		}
		float num4 = (double)num1 >= 0.0 ? num1 : num2;

		if ((double) num4 >= 0.0)
			*result = num4;
	}
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 스페어와 교차검사
///@param sphere : 바운딩 스페어
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool BoundingFrustum::Intersects( BoundingSphere sphere )
{
	bool result = false;
	Intersects(sphere, result);
	
	return result;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 스페어와 교차검사
///@param sphere : 바운딩 스페어
///@param result : 결과
//////////////////////////////////////////////////////////////////////////
void BoundingFrustum::Intersects( BoundingSphere sphere, bool& result )
{
	gjk.Reset();
	Vector3 result1 = cornerArray[0] - sphere.Center;
	if((double)result1.LengthSquared() < 9.99999974737875E-06)
		result1 = Vector3::UnitX;

	float num1 = MathHelper::FloatMaxValue; //float.MaxValue
	result = false;
	float num2;
	do
	{
		Vector3 v(-result1.X, -result1.Y, -result1.Z);
		Vector3 result2 = SupportMapping(v);
		Vector3 result3 = sphere.SupportMapping(result1);
		Vector3 result4 = result2 - result3;

		if((double)result1.X * (double)result4.X + (double)result1.Y * (double)result4.Y + (double)result1.Z * (double)result4.Z > 0.0)
		{
			return;
		}
		else
		{
			gjk.AddSupportPoint(result4);
			result1 = gjk.ClosestPoint();
			
			float num3 = num1;
			num1 = result1.LengthSquared();
			if((double)num3 - (double)num1 <= 9.99999974737875E-06 * (double)num3)
				return;
			else
				num2 = 4E-05f * gjk.MaxLengthSquared();
		}
	}
	while(!gjk.FullSimplex() && (double)num1 >= (double)num2);
	
	result = true;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 박스의 포함 여부 검사
///@param box : 바운딩 박스
///@return 포함 결과
//////////////////////////////////////////////////////////////////////////
ContainmentType BoundingFrustum::Contains( BoundingBox box )
{
	bool flag = false;
	
	for(int i = 0; i < 6; i++)
	{
		Plane plane = planes[i];
		
		switch(box.Intersects(plane))
		{
			case PlaneIntersectionType_Front:
				return ContainmentType_Disjoint;

			case PlaneIntersectionType_Intersecting:
				flag = true;
				break;
		}
	}
	
	if(!flag)
		return ContainmentType_Contains;
	else
		return ContainmentType_Intersects;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 프러스텀의 포함여부 검사
///@param frustum : 바운딩 프러스텀
///@return 포함 결과
//////////////////////////////////////////////////////////////////////////
ContainmentType BoundingFrustum::Contains( BoundingFrustum frustum )
{
	ContainmentType containmentType = ContainmentType_Disjoint;

	if(Intersects(frustum))
	{
		containmentType = ContainmentType_Contains;

		for(int index = 0; index < 8; ++index)
		{
			if(Contains(frustum.cornerArray[index]) == ContainmentType_Disjoint)
			{
				containmentType = ContainmentType_Intersects;
				
				break;
			}
		}
	}
	
	return containmentType;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 위치 벡터의 포함여부 검사
///@param point : 위치 벡터
///@return 포함 결과
//////////////////////////////////////////////////////////////////////////
ContainmentType BoundingFrustum::Contains( Vector3 point )
{
	for(int i = 0; i < 6; i++)
	{
		Plane plane = planes[i];

		if((double)((float)((double)plane.Normal.X * (double)point.X + (double)plane.Normal.Y * (double)point.Y + (double)plane.Normal.Z * (double)point.Z)+ plane.D) > 9.99999974737875E-06)
			return ContainmentType_Disjoint;
	}
	
	return ContainmentType_Contains;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 스페어의 포함여부 검사
///@param point : 위치 벡터
///@return 포함 결과
//////////////////////////////////////////////////////////////////////////
ContainmentType BoundingFrustum::Contains( BoundingSphere sphere )
{
	Vector3 vector3 = sphere.Center;
	float num1 = sphere.Radius;
	int num2 = 0;

	for(int i = 0; i < 6; i++)
	{
		Plane plane = planes[i];

		float num3 = (float)((double)plane.Normal.X * (double)vector3.X + (double)plane.Normal.Y * (double)vector3.Y + (double)plane.Normal.Z * (double)vector3.Z) + plane.D;
		
		if((double)num3 > (double)num1)
			return ContainmentType_Disjoint;
		else if ((double)num3 < -(double)num1)
			++num2;
	}

	if(num2 != 6)
		return ContainmentType_Intersects;
	else
		return ContainmentType_Contains;
}<file_sep>#include "stdafx.h"
#include "GameSkyBox.h"

GameSkyBox::GameSkyBox(wstring matFile, wstring meshFile)
	: GameModel(matFile, meshFile)
{

}

GameSkyBox::~GameSkyBox()
{

}
<file_sep>#include "stdafx.h"
#include "GameModel.h"

GameModel::GameModel(wstring matFile, wstring meshFile)
	: velocity(0, 0, 0)
{
	model = new Model();
	model->ReadMaterial(matFile);
	model->ReadMesh(meshFile);

	shader = new Shader(Shaders + L"999_GameModel.hlsl", "VS_Bone");
	for (Material* material : model->Materials())
		material->SetShader(shader);

	boneBuffer = new BoneBuffer();
	renderBuffer = new RenderBuffer();
}

GameModel::~GameModel()
{
	SAFE_DELETE(renderBuffer);
	SAFE_DELETE(boneBuffer);

	SAFE_DELETE(shader);
	SAFE_DELETE(model);
}

void GameModel::Velocity(D3DXVECTOR3 & vec)
{
	velocity = vec;
}

D3DXVECTOR3 GameModel::Velocity()
{
	return velocity;
}

void GameModel::AddPosition(D3DXVECTOR3 & vec)
{
	D3DXVECTOR3 temp = Position() + vec;

	Position(temp);
}

void GameModel::CalcPosition()
{
	if (D3DXVec3Length(&velocity) <= 0.0f)
		return;

	
	D3DXVECTOR3 vec(0, 0, 0);

	if (velocity.z != 0.0f)
		vec += Direction() * velocity.z;

	if (velocity.y != 0.0f)
		vec += Up() * velocity.y;

	if (velocity.x != 0.0f)
		vec += Right() * velocity.x;

	AddPosition(vec * Time::Delta());
}

void GameModel::Update()
{
	CalcPosition();

	D3DXMATRIX transformed = Transformed();
	model->CopyAbsoluteBoneTo(transformed, boneTransforms);
}

void GameModel::Render()
{
	if (Visible() == false) return;

	if(boneTransforms.size() !=0)
	boneBuffer->SetBones(&boneTransforms[0], boneTransforms.size());
	boneBuffer->SetVSBuffer(2);

	for (ModelMesh* mesh : model->Meshes())
	{
		int index = mesh->ParentBoneIndex();

		renderBuffer->Data.BoneNumber = index;
		renderBuffer->SetVSBuffer(3);

		mesh->Render();
	}
}
<file_sep>#include "stdafx.h"
#include "Model.h"
#include "ModelMesh.h"
#include "ModelBone.h"
#include "ModelAnimClip.h"

Model::Model()
{
	buffer = new ModelBuffer();
}

Model::~Model()
{
	SAFE_DELETE(buffer);

	for (Material* material : materials)
		SAFE_DELETE(material);

	for (ModelBone* bone : bones)
		SAFE_DELETE(bone);

	for (ModelMesh* mesh : meshes)
		SAFE_DELETE(mesh);

	for (ModelAnimClip* clip : clips)
		SAFE_DELETE(clip);
}

ModelMesh * Model::Mesh(wstring name)
{
	for (ModelMesh* mesh : meshes)
	{
		if (mesh->name == name)
			return mesh;
	}

	return NULL;
}

ModelBone * Model::Bone(wstring name)
{
	for (ModelBone* bone : bones)
	{
		if (bone->name == name)
			return bone;
	}

	return NULL;
}

ModelAnimClip * Model::Clip(wstring name)
{
	for (ModelAnimClip* clip : clips)
	{
		if (clip->Name() == name)
			return clip;
	}

	return NULL;
}

void Model::CopyAbsoluteBoneTo(vector<D3DXMATRIX>& transforms)
{
	transforms.clear();
	transforms.assign(bones.size(), D3DXMATRIX());

	for (size_t i = 0; i < bones.size(); i++)
	{
		ModelBone* bone = bones[i];

		if (bone->parent != NULL)
		{
			int index = bone->parent->index;
			transforms[i] = bone->transform * transforms[index];
		}
		else
			transforms[i] = bone->transform;
	}
}

void Model::CopyAbsoluteBoneTo(D3DXMATRIX matrix, vector<D3DXMATRIX>& transforms)
{
	transforms.clear();
	transforms.assign(bones.size(), D3DXMATRIX());

	for (size_t i = 0; i < bones.size(); i++)
	{
		ModelBone* bone = bones[i];

		if (bone->parent != NULL)
		{
			int index = bone->parent->index;
			transforms[i] = bone->transform * transforms[index];
		}
		else
			transforms[i] = bone->transform * matrix;
	}
}

void Models::Create()
{
}

void Models::Delete()
{
	for (pair<wstring, vector<Material *>> temp : materialMap)
	{
		for (Material* material : temp.second)
			SAFE_DELETE(material);
	}

	for (pair<wstring, MeshData> temp : meshDataMap)
	{
		MeshData data = temp.second;

		for (ModelBone* bone : data.Bones)
			SAFE_DELETE(bone);

		for (ModelMesh* mesh : data.Meshes)
			SAFE_DELETE(mesh);
	}
}
<file_sep>#include "Vector3.h"

#include <d3dx9math.h>
#include "Matrix.h"
#include "Quaternion.h"

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

const Vector3 Vector3::Zero = Vector3(0.0f, 0.0f, 0.0f);
const Vector3 Vector3::One = Vector3(1.0f, 1.0f, 1.0f);

const Vector3 Vector3::UnitX = Vector3(1.0f, 0.0f, 0.0f);
const Vector3 Vector3::UnitY = Vector3(0.0f, 1.0f, 0.0f);
const Vector3 Vector3::UnitZ = Vector3(0.0f, 0.0f, 1.0f);

const Vector3 Vector3::Up = Vector3(0.0f, 1.0f, 0.0f);
const Vector3 Vector3::Down = Vector3(0.0f, -1.0f, 0.0f);
const Vector3 Vector3::Right = Vector3(1.0f, 0.0f, 0.0f);
const Vector3 Vector3::Left = Vector3(-1.0f, 0.0f, 0.0f);
const Vector3 Vector3::Forward = Vector3(0.0f, 0.0f, -1.0f);
const Vector3 Vector3::Backward = Vector3(0.0f, 0.0f, 1.0f);

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


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
//////////////////////////////////////////////////////////////////////////
Vector3::Vector3( void )
{
	this->X = 0.0f;
	this->Y = 0.0f;
	this->Z = 0.0f;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
///@param X = Y = Z = value
//////////////////////////////////////////////////////////////////////////
Vector3::Vector3( float value )
{
	this->X = this->Y = this->Z = value;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
///@param x : X
///@param y : Y
///@param z : Z
//////////////////////////////////////////////////////////////////////////
Vector3::Vector3( float x, float y, float z )
{
	this->X = x;
	this->Y = y;
	this->Z = z;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief -
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Vector3::operator-( void )
{
	Vector3 vector3;
	vector3.X = -this->X;
	vector3.Y = -this->Y;
	vector3.Z = -this->Z;

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief ==
///@param value2 : 벡터
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool Vector3::operator==( const Vector3& value2 ) const
{
	if ((double)this->X == (double)value2.X && (double)this->Y == (double)value2.Y)
		return (double)this->Z == (double)value2.Z;
	else
		return false;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief !=
///@param value2 : 벡터
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool Vector3::operator!=( const Vector3& value2 ) const
{
	if ((double)this->X == (double)value2.X && (double)this->Y == (double)value2.Y)
		return (double)this->Z != (double)value2.Z;
	else
		return true;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief +
///@param value2 : 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Vector3::operator+( const Vector3& value2 ) const
{
	Vector3 vector3;
	vector3.X = this->X + value2.X;
	vector3.Y = this->Y + value2.Y;
	vector3.Z = this->Z + value2.Z;

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief -
///@param value2 : 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Vector3::operator-( const Vector3& value2 ) const
{
	Vector3 vector3;
	vector3.X = this->X - value2.X;
	vector3.Y = this->Y - value2.Y;
	vector3.Z = this->Z - value2.Z;

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief *
///@param value2 : 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Vector3::operator*( const Vector3& value2 ) const
{
	Vector3 vector3;
	vector3.X = this->X * value2.X;
	vector3.Y = this->Y * value2.Y;
	vector3.Z = this->Z * value2.Z;

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief *
///@param scaleFactor : 값
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Vector3::operator*( const float& scaleFactor ) const
{
	Vector3 vector3;
	vector3.X = this->X * scaleFactor;
	vector3.Y = this->Y * scaleFactor;
	vector3.Z = this->Z * scaleFactor;

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief /
///@param value2 : 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Vector3::operator/( const Vector3& value2 ) const
{
	Vector3 vector3;
	vector3.X = this->X / value2.X;
	vector3.Y = this->Y / value2.Y;
	vector3.Z = this->Z / value2.Z;

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief /
///@param divider : 값
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Vector3::operator/( const float& divider ) const
{
	float num = 1.0f / divider;

	Vector3 vector3;
	vector3.X = this->X * num;
	vector3.Y = this->Y * num;
	vector3.Z = this->Z * num;

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief +=
///@param value2 : 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
void Vector3::operator+=( const Vector3& value2 )
{
	*this = *this + value2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief -=
///@param value2 : 벡터 
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
void Vector3::operator-=( const Vector3& value2 )
{
	*this = *this - value2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief *=
///@param value2 : 벡터 
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
void Vector3::operator*=( const Vector3& value2 )
{
	*this = *this * value2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief /=
///@param scaleFactor : 값
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
void Vector3::operator*=( const float& scaleFactor )
{
	*this = *this * scaleFactor;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief /=
///@param value2 : 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
void Vector3::operator/=( const Vector3& value2 )
{
	*this = *this / value2;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief /=
///@param divider : 값
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
void Vector3::operator/=( const float& divider )
{
	*this = *this / divider;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 문자열로 변환
///@return 문자열
//////////////////////////////////////////////////////////////////////////
std::string Vector3::ToString()
{
	std::string temp;
	char val[255];

	sprintf(val, "{X:%#f ", X); temp += val; 
	sprintf(val, "Y:%#f ", Y); temp += val;
	sprintf(val, "Z:%#f}", Z); temp += val;

	return temp;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief D3DXVECTOR3로 변환
///@return D3DX 벡터 
//////////////////////////////////////////////////////////////////////////
D3DXVECTOR3 Vector3::ToD3DXVECTOR3()
{
	D3DXVECTOR3 vector3;
	vector3.x = X;
	vector3.y = Y;
	vector3.z = Z;

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 크기 계산
///@return 결과 값
//////////////////////////////////////////////////////////////////////////
float Vector3::Length()
{
	return (float)sqrt((double)this->X * (double)this->X + (double)this->Y * (double)this->Y + (double)this->Z * (double)this->Z);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 제곱으로 크기 계산
///@return 결과 값
//////////////////////////////////////////////////////////////////////////
float Vector3::LengthSquared()
{
	return (float)((double)this->X * (double)this->X + (double)this->Y * (double)this->Y + (double)this->Z * (double)this->Z);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 정규화
//////////////////////////////////////////////////////////////////////////
void Vector3::Normalize()
{
	float num = 1.0f / (float)sqrt((double)this->X * (double)this->X + (double)this->Y * (double)this->Y + (double)this->Z * (double)this->Z);

	this->X *= num;
	this->Y *= num;
	this->Z *= num;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 거리계산
///@param value1 : 벡터1
///@param value2 : 벡터2
///@return 결과 값
//////////////////////////////////////////////////////////////////////////
float Vector3::Distance( Vector3 value1, Vector3 value2 )
{
	float num1 = value1.X - value2.X;
	float num2 = value1.Y - value2.Y;
	float num3 = value1.Z - value2.Z;

	return (float)sqrt((double)num1 * (double)num1 + (double)num2 * (double)num2 + (double)num3 * (double)num3);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 제곱으로 거리계산
///@param value1 : 벡터1
///@param value2 : 벡터2
///@return 결과 값
//////////////////////////////////////////////////////////////////////////
float Vector3::DistanceSquared( Vector3 value1, Vector3 value2 )
{
	float num1 = value1.X - value2.X;
	float num2 = value1.Y - value2.Y;
	float num3 = value1.Z - value2.Z;

	return (float)((double)num1 * (double)num1 + (double)num2 * (double)num2 + (double)num3 * (double)num3);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 내적 계산
///@param value1 : 벡터1
///@param value2 : 벡터2
///@return 결과 값
//////////////////////////////////////////////////////////////////////////
float Vector3::Dot( Vector3 value1, Vector3 value2 )
{
	return (float)((double)value1.X * (double)value2.X + (double)value1.Y * (double)value2.Y + (double)value1.Z * (double)value2.Z);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 정규화
///@param value : 벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Vector3::Normalize( Vector3 value )
{
	float num = 1.0f / (float)sqrt((double)value.X * (double)value.X + (double)value.Y * (double)value.Y + (double)value.Z * (double)value.Z);

	Vector3 vector3;
	vector3.X = value.X * num;
	vector3.Y = value.Y * num;
	vector3.Z = value.Z * num;

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 외적 계산
///@param vector1 : 벡터1
///@param vector2 : 벡터2
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Vector3::Cross( Vector3 vector1, Vector3 vector2 )
{
	Vector3 vector3;
	vector3.X = (float)((double)vector1.Y * (double)vector2.Z - (double)vector1.Z * (double)vector2.Y);
	vector3.Y = (float)((double)vector1.Z * (double)vector2.X - (double)vector1.X * (double)vector2.Z);
	vector3.Z = (float)((double)vector1.X * (double)vector2.Y - (double)vector1.Y * (double)vector2.X);

	return vector3;	
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 반사값
///@param vector : 벡터
///@param normal : 노멀벡터
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Vector3::Reflect( Vector3 vector, Vector3 normal )
{
	float num = (float)((double)vector.X * (double)normal.X + (double)vector.Y * (double)normal.Y + (double)vector.Z * (double)normal.Z);

	Vector3 vector3;
	vector3.X = vector.X - 2.0f * num * normal.X;
	vector3.Y = vector.Y - 2.0f * num * normal.Y;
	vector3.Z = vector.Z - 2.0f * num * normal.Z;

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 두 벡터 중 작은 벡터
///@param value1 : 벡터1
///@param value2 : 벡터2
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Vector3::Min( Vector3 value1, Vector3 value2 )
{
	Vector3 vector3;
	vector3.X = (double)value1.X < (double)value2.X ? value1.X : value2.X;
	vector3.Y = (double)value1.Y < (double)value2.Y ? value1.Y : value2.Y;
	vector3.Z = (double)value1.Z < (double)value2.Z ? value1.Z : value2.Z;

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 두 벡터 중 큰 벡터
///@param value1 : 벡터1
///@param value2 : 벡터2
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Vector3::Max( Vector3 value1, Vector3 value2 )
{
	Vector3 vector3;
	vector3.X = (double)value1.X > (double)value2.X ? value1.X : value2.X;
	vector3.Y = (double)value1.Y > (double)value2.Y ? value1.Y : value2.Y;
	vector3.Z = (double)value1.Z > (double)value2.Z ? value1.Z : value2.Z;

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 해당 벡터가 최소값보다 작을 경우 최소값, 반대의 경우 최대값
///@param value1 : 벡터
///@param min : 최소값 벡터
///@param max : 최대값 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Vector3::Clamp( Vector3 value1, Vector3 min, Vector3 max )
{
	float num1 = value1.X;
	float num2 = (double)num1 > (double)max.X ? max.X : num1;
	float num3 = (double)num2 < (double)min.X ? min.X : num2;

	float num4 = value1.Y;
	float num5 = (double)num4 > (double)max.Y ? max.Y : num4;
	float num6 = (double)num5 < (double)min.Y ? min.Y : num5;

	float num7 = value1.Z;
	float num8 = (double)num7 > (double)max.Z ? max.Z : num7;
	float num9 = (double)num8 < (double)min.Z ? min.Z : num8;

	Vector3 vector3;
	vector3.X = num3;
	vector3.Y = num6;
	vector3.Z = num9;

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 두 벡터의 선형보간
///@param value1 : 벡터1
///@param value2 : 벡터2
///@param amount : 보간값
///@return 결과벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Vector3::Lerp( Vector3 value1, Vector3 value2, float amount )
{
	Vector3 vector3;
	vector3.X = value1.X + (value2.X - value1.X) * amount;
	vector3.Y = value1.Y + (value2.Y - value1.Y) * amount;
	vector3.Z = value1.Z + (value2.Z - value1.Z) * amount;

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 두 벡터를 부드럽게 보간
///@param value1 : 벡터1
///@param value2 : 벡터2
///@param amount : 보간값
///@return 결과벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Vector3::SmoothStep( Vector3 value1, Vector3 value2, float amount )
{
	amount = (double)amount > 1.0 ? 1.0f : ((double)amount < 0.0 ? 0.0f : amount);
	amount = (float)((double)amount * (double)amount * (3.0 - 2.0 * (double)amount));

	Vector3 vector3;
	vector3.X = value1.X + (value2.X - value1.X)* amount;
	vector3.Y = value1.Y + (value2.Y - value1.Y)* amount;
	vector3.Z = value1.Z + (value2.Z - value1.Z)* amount;

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 카트뮬-롬 보간
///@param value1 : 벡터1
///@param value2 : 벡터2
///@param value3 : 벡터3
///@param value4 : 벡터4
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Vector3::CatmullRom( Vector3 value1, Vector3 value2, Vector3 value3, Vector3 value4, float amount )
{
	float num1 = amount * amount;
	float num2 = amount * num1;

	Vector3 vector3;
	vector3.X = (float)(0.5 * (2.0 * (double)value2.X + (-(double)value1.X + (double)value3.X)* (double)amount + (2.0 * (double)value1.X - 5.0 * (double)value2.X + 4.0 * (double)value3.X - (double)value4.X)* (double)num1 + (-(double)value1.X + 3.0 * (double)value2.X - 3.0 * (double)value3.X + (double)value4.X)* (double)num2));
	vector3.Y = (float)(0.5 * (2.0 * (double)value2.Y + (-(double)value1.Y + (double)value3.Y)* (double)amount + (2.0 * (double)value1.Y - 5.0 * (double)value2.Y + 4.0 * (double)value3.Y - (double)value4.Y)* (double)num1 + (-(double)value1.Y + 3.0 * (double)value2.Y - 3.0 * (double)value3.Y + (double)value4.Y)* (double)num2));
	vector3.Z = (float)(0.5 * (2.0 * (double)value2.Z + (-(double)value1.Z + (double)value3.Z)* (double)amount + (2.0 * (double)value1.Z - 5.0 * (double)value2.Z + 4.0 * (double)value3.Z - (double)value4.Z)* (double)num1 + (-(double)value1.Z + 3.0 * (double)value2.Z - 3.0 * (double)value3.Z + (double)value4.Z)* (double)num2));

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 에르미트 보간
///@param value1 : 벡터1
///@param tagent1 : 벡터1의 탄젠트 벡터
///@param value2 : 벡터2
///@param tagent2 : 벡터2 탄젠트 벡터
///@param amount : 보간값
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Vector3::Hermite( Vector3 value1, Vector3 tangent1, Vector3 value2, Vector3 tangent2, float amount )
{
	float num1 = amount * amount;
	float num2 = amount * num1;
	float num3 = (float)(2.0 * (double)num2 - 3.0 * (double)num1 + 1.0);
	float num4 = (float)(-2.0 * (double)num2 + 3.0 * (double)num1);
	float num5 = num2 - 2.0f * num1 + amount;
	float num6 = num2 - num1;

	Vector3 vector3;
	vector3.X = (float)((double)value1.X * (double)num3 + (double)value2.X * (double)num4 + (double)tangent1.X * (double)num5 + (double)tangent2.X * (double)num6);
	vector3.Y = (float)((double)value1.Y * (double)num3 + (double)value2.Y * (double)num4 + (double)tangent1.Y * (double)num5 + (double)tangent2.Y * (double)num6);
	vector3.Z = (float)((double)value1.Z * (double)num3 + (double)value2.Z * (double)num4 + (double)tangent1.Z * (double)num5 + (double)tangent2.Z * (double)num6);

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 매트릭스에 의한 벡터 변환
///@param position : 벡터
///@param matrix : 매트릭스
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Vector3::Transform( Vector3 position, Matrix matrix )
{
	float num1 = (float)((double)position.X * (double)matrix.M11 + (double)position.Y * (double)matrix.M21 + (double)position.Z * (double)matrix.M31)+ matrix.M41;
	float num2 = (float)((double)position.X * (double)matrix.M12 + (double)position.Y * (double)matrix.M22 + (double)position.Z * (double)matrix.M32)+ matrix.M42;
	float num3 = (float)((double)position.X * (double)matrix.M13 + (double)position.Y * (double)matrix.M23 + (double)position.Z * (double)matrix.M33)+ matrix.M43;

	Vector3 vector3;
	vector3.X = num1;
	vector3.Y = num2;
	vector3.Z = num3;

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 쿼터니온에 의한 벡터 변환
///@param value : 벡터
///@param rotation : 쿼터니온
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Vector3::Transform( Vector3 value, Quaternion rotation )
{
	float num1 = rotation.X + rotation.X;
	float num2 = rotation.Y + rotation.Y;
	float num3 = rotation.Z + rotation.Z;

	float num4 = rotation.W * num1;
	float num5 = rotation.W * num2;
	float num6 = rotation.W * num3;
	float num7 = rotation.X * num1;
	float num8 = rotation.X * num2;
	float num9 = rotation.X * num3;

	float num10 = rotation.Y * num2;
	float num11 = rotation.Y * num3;
	float num12 = rotation.Z * num3;

	float num13 = (float)((double)value.X * (1.0 - (double)num10 - (double)num12)+ (double)value.Y * ((double)num8 - (double)num6)+ (double)value.Z * ((double)num9 + (double)num5));
	float num14 = (float)((double)value.X * ((double)num8 + (double)num6) + (double)value.Y * (1.0 - (double)num7 - (double)num12)+ (double)value.Z * ((double)num11 - (double)num4));
	float num15 = (float)((double)value.X * ((double)num9 - (double)num5) + (double)value.Y * ((double)num11 + (double)num4)+ (double)value.Z * (1.0 - (double)num7 - (double)num10));

	Vector3 vector3;
	vector3.X = num13;
	vector3.Y = num14;
	vector3.Z = num15;

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 매트릭스에 의한 노멀벡터 변환
///@param normal : 법선 벡터
///@param matrix : 매트릭스
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Vector3::TransformNormal( Vector3 normal, Matrix matrix )
{
	float num1 = (float)((double)normal.X * (double)matrix.M11 + (double)normal.Y * (double)matrix.M21 + (double)normal.Z * (double)matrix.M31);
	float num2 = (float)((double)normal.X * (double)matrix.M12 + (double)normal.Y * (double)matrix.M22 + (double)normal.Z * (double)matrix.M32);
	float num3 = (float)((double)normal.X * (double)matrix.M13 + (double)normal.Y * (double)matrix.M23 + (double)normal.Z * (double)matrix.M33);

	Vector3 vector3;
	vector3.X = num1;
	vector3.Y = num2;
	vector3.Z = num3;

	return vector3;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 매트릭스에 의한 위치(정점)벡터 변환
///@param position : 위치 벡터
///@param matrix : 매트릭스
///@return 결과 벡터
//////////////////////////////////////////////////////////////////////////
Vector3 Vector3::TransformCoord( Vector3 position, Matrix matrix )
{
	float num1 = (matrix.M11 * position.X) + (matrix.M21 * position.Y) + (matrix.M31 * position.Z) + matrix.M41;
	float num2 = (matrix.M12 * position.X) + (matrix.M22 * position.Y) + (matrix.M32 * position.Z) + matrix.M42;
	float num3 = (matrix.M13 * position.X) + (matrix.M23 * position.Y) + (matrix.M33 * position.Z) + matrix.M43;
	float num4 = (matrix.M14 * position.X) + (matrix.M24 * position.Y) + (matrix.M34 * position.Z) + matrix.M44;

	return Vector3((num1 / num4), (num2 / num4), (num3 / num4));
}<file_sep>#pragma once

#include "../Core/Vector3.h"

enum PlaneIntersectionType;
enum ContainmentType;

class BoundingBox;
class BoundingFrustum;
class Ray;
class Plane;

//////////////////////////////////////////////////////////////////////////
///@brief 충돌 구
//////////////////////////////////////////////////////////////////////////
class BoundingSphere
{
public:
	BoundingSphere(void);
	BoundingSphere(Vector3 center, float radius);

	bool operator ==(const BoundingSphere& value) const;
	bool operator !=(const BoundingSphere& value) const;

	Vector3 SupportMapping(Vector3 v);

	static BoundingSphere CreateMerged(BoundingSphere original, BoundingSphere additional);
	static BoundingSphere CreateFromBoundingBox(BoundingBox box);

	bool Intersects(BoundingBox box);
	bool Intersects(BoundingFrustum frustum);
	PlaneIntersectionType Intersects(Plane plane);
	bool Intersects(Ray ray, float& result);
	bool Intersects(BoundingSphere sphere);

	ContainmentType Contains(BoundingBox box);
	ContainmentType Contains(BoundingFrustum frustum);
	ContainmentType Contains(Vector3 point);
	ContainmentType Contains(BoundingSphere sphere);

	BoundingSphere Transform(Matrix matrix);

public:
	Vector3 Center;///< 중심점 위치
	float Radius;///< 반지름
};<file_sep>#include "BoundingBox.h"

#include <assert.h>
#include "Bounding.h"
#include "BoundingSphere.h"
#include "BoundingFrustum.h"
#include "Ray.h"

#include "../Core/Plane.h"
#include "../Core/MathHelper.h"

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

const int BoundingBox::CornerCount = 8;

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


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
//////////////////////////////////////////////////////////////////////////
BoundingBox::BoundingBox( void )
{
	this->Min = Vector3::Zero;
	this->Max = Vector3::Zero;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
///@param min : 최소 위치벡터
///@param max : 최대 위치벡터
//////////////////////////////////////////////////////////////////////////
BoundingBox::BoundingBox( Vector3 min, Vector3 max )
{
	this->Min = min;
	this->Max = max;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief ==
///@param value : 바운딩 박스
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool BoundingBox::operator==( const BoundingBox& value ) const
{
	if(this->Min == value.Min)
		return this->Max == value.Max;
	else
		return false;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief !=
///@param value : 바운딩 박스
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool BoundingBox::operator!=( const BoundingBox& value ) const
{
	if(!(this->Min != value.Min))
		return this->Max != value.Max;
	else
		return true;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 코너 위치
///@param pCorner : Vector[8]
//////////////////////////////////////////////////////////////////////////
void BoundingBox::GetCorners( Vector3* pCorner )
{
	assert(pCorner != NULL);

	pCorner[0] = Vector3(Min.X, Max.Y, Max.Z);
	pCorner[1] = Vector3(Max.X, Max.Y, Max.Z);
	pCorner[2] = Vector3(Max.X, Min.Y, Max.Z);
	pCorner[3] = Vector3(Min.X, Min.Y, Max.Z);
	pCorner[4] = Vector3(Min.X, Max.Y, Min.Z);
	pCorner[5] = Vector3(Max.X, Max.Y, Min.Z);
	pCorner[6] = Vector3(Max.X, Min.Y, Min.Z);
	pCorner[7] = Vector3(Min.X, Min.Y, Min.Z);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 문자열로 변환
///@param 문자열
//////////////////////////////////////////////////////////////////////////
std::string BoundingBox::ToString()
{
	std::string temp;
	char val[255];

	sprintf(val, "{ Min:{X:%#f ", Min.X); temp += val; 
	sprintf(val, "Y:%#f ", Min.Y); temp += val;
	sprintf(val, "Z:%#f}, ", Min.Z); temp += val;

	sprintf(val, "Max:{X:%#f ", Max.X); temp += val; 
	sprintf(val, "Y:%#f ", Max.Y); temp += val;
	sprintf(val, "Z:%#f}}, ", Max.Z); temp += val;

	return temp;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 서포트 매핑
///@param v : 벡터
///@return 결과
//////////////////////////////////////////////////////////////////////////
Vector3 BoundingBox::SupportMapping( Vector3 v )
{
	Vector3 result;
	result.X = (double)v.X >= 0.0 ? Max.X : Min.X;
	result.Y = (double)v.Y >= 0.0 ? Max.Y : Min.Y;
	result.Z = (double)v.Z >= 0.0 ? Max.Z : Min.Z;

	return result;
}
//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 박스 2개를 합친다
///@param original : 바운딩 박스1
///@param additional : 바운딩 박스2
///@return 결과 바운딩박스
//////////////////////////////////////////////////////////////////////////
BoundingBox BoundingBox::CreateMerged( BoundingBox original, BoundingBox additional )
{
	BoundingBox boundingBox;
	boundingBox.Min = Vector3::Min(original.Min, additional.Min);
	boundingBox.Max = Vector3::Max(original.Max, additional.Max);

	return boundingBox;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 스페어로부터 바운딩 박스 생성
///@param sphere : 바운딩 스페어
///@return 결과 바운딩박스
//////////////////////////////////////////////////////////////////////////
BoundingBox BoundingBox::CreateFromSphere( BoundingSphere sphere )
{
	BoundingBox boundingBox;
	boundingBox.Min.X = sphere.Center.X - sphere.Radius;
	boundingBox.Min.Y = sphere.Center.Y - sphere.Radius;
	boundingBox.Min.Z = sphere.Center.Z - sphere.Radius;
	boundingBox.Max.X = sphere.Center.X + sphere.Radius;
	boundingBox.Max.Y = sphere.Center.Y + sphere.Radius;
	boundingBox.Max.Z = sphere.Center.Z + sphere.Radius;

	return boundingBox;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 박스와 교차 검사
///@param box : 바운딩 박스
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool BoundingBox::Intersects( BoundingBox box )
{
	if ((double)Max.X < (double)box.Min.X || (double)Min.X > (double)box.Max.X || ((double)Max.Y < (double)box.Min.Y || (double)Min.Y > (double)box.Max.Y)|| ((double)Max.Z < (double)box.Min.Z || (double)Min.Z > (double)box.Max.Z))
		return false;
	else
		return true;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 프러스텀과 교차 검사
///@param frustum : 바운딩 프러스텀
//////////////////////////////////////////////////////////////////////////
bool BoundingBox::Intersects( BoundingFrustum frustum )
{	
	return frustum.Intersects(*this);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 평면과의 교차 검사
///@param plane : 평면
///@return 교차 결과
//////////////////////////////////////////////////////////////////////////
PlaneIntersectionType BoundingBox::Intersects( Plane plane )
{
	Vector3 vector3_1;
	vector3_1.X = (double)plane.Normal.X >= 0.0 ? Min.X : Max.X;
	vector3_1.Y = (double)plane.Normal.Y >= 0.0 ? Min.Y : Max.Y;
	vector3_1.Z = (double)plane.Normal.Z >= 0.0 ? Min.Z : Max.Z;

	Vector3 vector3_2;
	vector3_2.X = (double)plane.Normal.X >= 0.0 ? Max.X : Min.X;
	vector3_2.Y = (double)plane.Normal.Y >= 0.0 ? Max.Y : Min.Y;
	vector3_2.Z = (double)plane.Normal.Z >= 0.0 ? Max.Z : Min.Z;

	if ((double)plane.Normal.X * (double)vector3_1.X + (double)plane.Normal.Y * (double)vector3_1.Y + (double)plane.Normal.Z * (double)vector3_1.Z + (double)plane.D > 0.0)
		return PlaneIntersectionType_Front;
	else if ((double)plane.Normal.X * (double)vector3_2.X + (double)plane.Normal.Y * (double)vector3_2.Y + (double)plane.Normal.Z * (double)vector3_2.Z + (double)plane.D < 0.0)
		return PlaneIntersectionType_Back;
	else
		return PlaneIntersectionType_Intersecting;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 레이와의 교차 검사
///@param ray : 레이
///@param result : 결과
///@warning
///		교차가 되지 않은 결과 result는 0.0f이 절대 아니다!
///		result == NULL 이다!!!!!
//////////////////////////////////////////////////////////////////////////
bool BoundingBox::Intersects( Ray ray, float* result )
{
	if(result != NULL)
	{
		delete result;
		result = NULL;
	}

	float num1 = 0.0f;
	float num2 = MathHelper::FloatMaxValue;
	
	
	//1. ray.Direction.X
	if((double)MathHelper::Abs(ray.Direction.X) < 9.99999997475243E-07)
	{
		if((double)ray.Position.X < (double)Min.X || (double)ray.Position.X > (double)Max.X)
			return false;
	}
	else
	{
		float num3 = 1.0f / ray.Direction.X;
		float num4 = (Min.X - ray.Position.X)* num3;
		float num5 = (Max.X - ray.Position.X)* num3;

		if((double)num4 > (double)num5)
		{
			float num6 = num4;
			num4 = num5;
			num5 = num6;
		}
		
		num1 = MathHelper::Max(num4, num1);
		num2 = MathHelper::Min(num5, num2);
		
		if((double)num1 > (double)num2)
			return false;
	}
	

	//2. ray.Direction.Y
	if((double)MathHelper::Abs(ray.Direction.Y) < 9.99999997475243E-07)
	{
		if ((double)ray.Position.Y < (double)Min.Y || (double)ray.Position.Y >(double)Max.Y)
			return false;
	}
	else
	{
		float num3 = 1.0f / ray.Direction.Y;
		float num4 = (Min.Y - ray.Position.Y) * num3;
		float num5 = (Max.Y - ray.Position.Y) * num3;

		if((double)num4 > (double)num5)
		{
			float num6 = num4;
			num4 = num5;
			num5 = num6;
		}

		num1 = MathHelper::Max(num4, num1);
		num2 = MathHelper::Min(num5, num2);
		
		if((double)num1 > (double)num2)
			return false;
	}


	//3. ray.Direction.Z
	if((double)MathHelper::Abs(ray.Direction.Z) < 9.99999997475243E-07)
	{
		if((double)ray.Position.Z < (double)Min.Z || (double)ray.Position.Z > (double)Max.Z)
			return false;
	}
	else
	{
		float num3 = 1.0f / ray.Direction.Z;
		float num4 = (Min.Z - ray.Position.Z) * num3;
		float num5 = (Max.Z - ray.Position.Z) * num3;
		
		if((double)num4 > (double)num5)
		{
			float num6 = num4;
			num4 = num5;
			num5 = num6;
		}

		num1 = MathHelper::Max(num4, num1);
		float num7 = MathHelper::Min(num5, num2);
		
		if((double)num1 > (double)num7)
			return false;
	}

	result = new float(num1);
	return true;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 스페어와 교차 검사
///@param sphere : 바운딩 스페어
///@return 결과
//////////////////////////////////////////////////////////////////////////
bool BoundingBox::Intersects( BoundingSphere sphere )
{
	Vector3 result1 = Vector3::Clamp(sphere.Center, Min, Max);
	float result2 = Vector3::DistanceSquared(sphere.Center, result1);
	
	if((double)result2 <= (double)sphere.Radius * (double)sphere.Radius)
		return true;
	else
		return false;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 박스 포함 검사
///@param box : 바운딩 박스
///@return 포함 결과
//////////////////////////////////////////////////////////////////////////
ContainmentType BoundingBox::Contains( BoundingBox box )
{
	if ((double)Max.X < (double)box.Min.X || (double)Min.X > (double)box.Max.X || ((double)Max.Y < (double)box.Min.Y || (double)Min.Y > (double)box.Max.Y) || ((double)Max.Z < (double)box.Min.Z || (double)Min.Z > (double)box.Max.Z))
		return ContainmentType_Disjoint;
	else if ((double)Min.X > (double)box.Min.X || (double)box.Max.X > (double)Max.X || ((double)Min.Y > (double)box.Min.Y || (double)box.Max.Y > (double)Max.Y)|| ((double)Min.Z > (double)box.Min.Z || (double)box.Max.Z > (double)Max.Z))
		return ContainmentType_Intersects;
	else
		return ContainmentType_Contains;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 프러스텀 포함 검사
///@param box : 바운딩 박스
///@return 포함 결과
//////////////////////////////////////////////////////////////////////////
ContainmentType BoundingBox::Contains( BoundingFrustum frustum )
{
	if(!frustum.Intersects(*this))
	{
		return ContainmentType_Disjoint;
	}
	else
	{
		for(int i = 0; i < 8; i++)
		{
			Vector3 point = frustum.cornerArray[i];
			
			if(Contains(point) == ContainmentType_Disjoint)
				return ContainmentType_Intersects;
		}
		
		return ContainmentType_Contains;
	}
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 위치 벡터 포함 검사
///@param point : 위치 벡터
///@return 포함 결과
//////////////////////////////////////////////////////////////////////////
ContainmentType BoundingBox::Contains( Vector3 point )
{
	if ((double)Min.X > (double)point.X || (double)point.X > (double)Max.X || ((double)Min.Y > (double)point.Y || (double)point.Y > (double)Max.Y)|| ((double)Min.Z > (double)point.Z || (double)point.Z > (double)Max.Z))
		return ContainmentType_Disjoint;
	else
		return ContainmentType_Contains;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 스페어 포함 검사
///@param point : 위치 벡터
///@return 포함 결과
//////////////////////////////////////////////////////////////////////////
ContainmentType BoundingBox::Contains( BoundingSphere sphere )
{
	Vector3 result1 = Vector3::Clamp(sphere.Center, Min, Max);
	float result2 = Vector3::DistanceSquared(sphere.Center, result1);
	float num = sphere.Radius;
	
	if((double)result2 > (double)num * (double)num)
		return ContainmentType_Disjoint;
	else if ((double)Min.X + (double)num > (double)sphere.Center.X || (double)sphere.Center.X > (double)Max.X - (double)num || ((double)Max.X - (double)Min.X <= (double)num || (double)Min.Y + (double)num > (double)sphere.Center.Y)|| ((double)sphere.Center.Y > (double)Max.Y - (double)num || (double)Max.Y - (double)Min.Y <= (double)num || ((double)Min.Z + (double)num > (double)sphere.Center.Z || (double)sphere.Center.Z > (double)Max.Z - (double)num))|| (double)Max.X - (double)Min.X <= (double)num)
		return ContainmentType_Intersects;
	else
		return ContainmentType_Contains;
}<file_sep>#pragma once

#include <string>
#pragma warning( disable : 4996)

struct D3DXMATRIX;
class Vector3;
class Quaternion;
class Plane;

//////////////////////////////////////////////////////////////////////////
///@brief 행렬
//////////////////////////////////////////////////////////////////////////
class Matrix
{
public:
	Matrix(void);
	Matrix(float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24, float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44);

	Vector3 Up();			void Up(Vector3 value);
	Vector3 Down();			void Down(Vector3 value);
	Vector3 Right();		void Right(Vector3 value);
	Vector3 Left();			void Left(Vector3 value);
	Vector3 Forward();		void Forward(Vector3 value);
	Vector3 Backward();		void Backward(Vector3 value);
	Vector3 Translate();	void Translate(Vector3 value);

	Matrix operator -();

	bool operator ==(const Matrix& matrix2) const;
	bool operator !=(const Matrix& matrix2) const;

	Matrix operator +(const Matrix& matrix2) const;
	Matrix operator -(const Matrix& matrix2) const;
	Matrix operator *(const Matrix& matrix2) const;
	Matrix operator *(const float& scaleFactor) const;
	Matrix operator /(const Matrix& matrix2) const;
	Matrix operator /(const float& divider) const;

	void operator +=(const Matrix& matrix2);
	void operator -=(const Matrix& matrix2);
	void operator *=(const Matrix& matrix2);
	void operator *=(const float& scaleFactor);
	void operator /=(const Matrix& matrix2);
	void operator /=(const float& divider);

	//////////////////////////////////////////////////////////////////////////
	///@brief float형의 *연산 처리
	///@param scalefactor : 값
	///@param matrix2 : 매트릭스
	///@return 결과 매트릭스
	//////////////////////////////////////////////////////////////////////////
	friend Matrix operator *(const float scaleFactor, const Matrix& matrix2)
	{
		return matrix2 * scaleFactor;
	}
	//////////////////////////////////////////////////////////////////////////

	std::string ToString();
	D3DXMATRIX ToD3DXMATRIX();

	float Determinant();

	static Matrix CreateBillboard(Vector3 objectPosition, Vector3 cameraPosition, Vector3 cameraUpVector, Vector3* cameraForwardVector=NULL);
	
	static Matrix CreateTranslation(Vector3 position);
	static Matrix CreateTranslation(float xPosition, float yPosition, float zPosition);
	
	static Matrix CreateScale(Vector3 scales);
	static Matrix CreateScale(float xScale, float yScale, float zScale);
	static Matrix CreateScale(float scale);

	static Matrix CreateRotationX(float radians);
	static Matrix CreateRotationY(float radians);
	static Matrix CreateRotationZ(float radians);
	static Matrix CreateFromAxisAngle(Vector3 axis, float angle);

	static Matrix CreatePerspective(float width, float height, float nearPlaneDistance, float farPlaneDistance);
	static Matrix CreatePerspectiveFieldOfView(float fieldOfView, float aspectRatio, float nearPlaneDistance, float farPlaneDistance);

	static Matrix CreateLookAt(Vector3 cameraPosition, Vector3 cameraTarget, Vector3 cameraUpVector);
	static Matrix CreateWorld(Vector3 position, Vector3 forward, Vector3 up);
	static Matrix CreateFromQuaternion(Quaternion quaternion);
	static Matrix CreateFromYawPitchRoll(float yaw, float pitch, float roll);
	static Matrix CreateShadow(Vector3 lightDirection, Plane plane);
	static Matrix CreateReflection(Plane value);
	static Matrix CreateOrthographic(float width, float height, float zNearPlane, float zFarPlane);

	static Matrix Transform(Matrix value, Quaternion rotation);
	static Matrix Transpose(Matrix matrix);
	static Matrix Invert(Matrix matrix);
	static Matrix Lerp(Matrix matrix1, Matrix matrix2, float amount);	

public:
	const static Matrix Identity;

	float M11;
	float M12;
	float M13;
	float M14;

	float M21;
	float M22;
	float M23;
	float M24;

	float M31;
	float M32;
	float M33;
	float M34;

	float M41;
	float M42;
	float M43;
	float M44;
};<file_sep>#pragma once

class BoundingFrustum;

namespace Gizmo
{
	class Gizmo
	{
	public:
		friend class Gizmos;

	public:
		class Buffer : public ShaderBuffer
		{
		public:
			Buffer() : ShaderBuffer(&Data, sizeof(Data))
			{
				Data.Color = D3DXCOLOR(1, 1, 1, 1);
				Data.HighlightColor = D3DXCOLOR(0, 0, 0, 1);
				Data.IsHighlight = 0;
			}
			struct Struct
			{
				D3DXCOLOR Color;
				D3DXCOLOR HighlightColor;
				int IsHighlight;
				int Padding[3];
			}Data;
		};
	public:
		~Gizmo();

		void Render();
		void UpdateVertexData();
	public:
		D3DXCOLOR color, highlightColor;
		D3DXMATRIX rootWorld;
		D3DXMATRIX localWorld;

		vector<VertexColor> vertexData;
		vector<UINT> indexData;
		bool bHighlight;
	private:
		Gizmo();
		Gizmo(vector<D3DXVECTOR3>&& positions, vector<UINT>&& indices);

		void Init();
		void CreateBuffer();

	private:
		D3D11_PRIMITIVE_TOPOLOGY topology;
		WorldBuffer* worldBuffer;
		ID3D11Buffer* vertexBuffer, *indexBuffer;

		Shader* shader;
		Buffer* buffer;
	};

	class Gizmos
	{
	public:
		static Gizmo* Quad(D3DXVECTOR3 center, D3DXVECTOR3 normal, D3DXVECTOR3 up, float width, float height);

		static Gizmo* Cube(D3DXVECTOR3 min, D3DXVECTOR3 max);
		static Gizmo* Sphere(D3DXVECTOR3 center, float radius);
		static Gizmo* Frustum(BoundingFrustum* frustum);

		static Gizmo* Line(D3DXVECTOR3 start, D3DXVECTOR3 end);
		static Gizmo* Ray(D3DXVECTOR3 start, D3DXVECTOR3 dir, float length = 10000.0f);

		static Gizmo* WireCube(D3DXVECTOR3 min, D3DXVECTOR3 max);
		static Gizmo* WireSphere(D3DXVECTOR3 center, float radius);

		static Gizmo* Scale();
		static Gizmo* Rotate();
		static Gizmo* Translate();
	};
}<file_sep>#include "Plane.h"

#include <d3dx9math.h>
#include "Vector4.h"
#include "Matrix.h"
#include "MathHelper.h"
#include "Quaternion.h"

#include "../Bounding/Bounding.h"
#include "../Bounding/BoundingBox.h"
#include "../Bounding/BoundingFrustum.h"
#include "../Bounding/BoundingSphere.h"

//////////////////////////////////////////////////////////////////////////
///@brief 생성자
//////////////////////////////////////////////////////////////////////////
Plane::Plane( void )
{
	this->D = 0.0f;
	this->Normal = Vector3::Zero;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
///@param a : 노멀축 X
///@param b : 노멀축 Y
///@param c : 노멀축 Z
///@param d : 거리값
//////////////////////////////////////////////////////////////////////////
Plane::Plane( float a, float b, float c, float d )
{
	this->Normal.X = a;
	this->Normal.Y = b;
	this->Normal.Z = c;
	this->D = d;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
///@param normal : 노멀 벡터
///@param d : 거리값
//////////////////////////////////////////////////////////////////////////
Plane::Plane( Vector3 normal, float d )
{
	this->Normal = normal;
	this->D = d;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
///@param value : 4D 벡터(XYZ, W=거리)
//////////////////////////////////////////////////////////////////////////
Plane::Plane( Vector4 value )
{
	this->Normal.X = value.X;
	this->Normal.Y = value.Y;
	this->Normal.Z = value.Z;
	this->D = value.W;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 생성자
///@param point1 : 위치 벡터1
///@param point2 : 위치 벡터2
///@param point3 : 위치 벡터3
//////////////////////////////////////////////////////////////////////////
Plane::Plane( Vector3 point1, Vector3 point2, Vector3 point3 )
{
	float xValue1 = point2.X - point1.X;
	float yValue1 = point2.Y - point1.Y;
	float zValue1 = point2.Z - point1.Z;
	float xValue2 = point3.X - point1.X;
	float yValue2 = point3.Y - point1.Y;
	float zValue2 = point3.Z - point1.Z;

	float num1 = (float)((double)yValue1 * (double)zValue2 - (double)zValue1 * (double)yValue2);
	float num2 = (float)((double)zValue1 * (double)xValue2 - (double)xValue1 * (double)zValue2);
	float num3 = (float)((double)xValue1 * (double)yValue2 - (double)yValue1 * (double)xValue2);
	float num4 = 1.0f / (float)sqrt((double)num1 * (double)num1 + (double)num2 * (double)num2 + (double)num3 * (double)num3);
	
	this->Normal.X = num1 * num4;
	this->Normal.Y = num2 * num4;
	this->Normal.Z = num3 * num4;
	this->D = (float)-((double)this->Normal.X * (double)point1.X + (double)this->Normal.Y * (double)point1.Y + (double)this->Normal.Z * (double)point1.Z);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief ==
///@param value : 평면
//////////////////////////////////////////////////////////////////////////
bool Plane::operator==( const Plane& value )const
{
	if((double)Normal.X == (double)value.Normal.X && (double)Normal.Y == (double)value.Normal.Y && (double)Normal.Z == (double)value.Normal.Z)
		return (double)D == (double)value.D;
	else
		return false;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief !=
///@param value : 평면
//////////////////////////////////////////////////////////////////////////
bool Plane::operator!=( const Plane& value )const
{
	if((double)Normal.X == (double)value.Normal.X && (double)Normal.Y == (double)value.Normal.Y && (double)Normal.Z == (double)value.Normal.Z)
		return (double)D != (double)value.D;
	else
		return true;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 문자열로 변환
///@param 문자열
//////////////////////////////////////////////////////////////////////////
std::string Plane::ToString()
{
	std::string temp;
	char val[255];

	temp += "{Normal:" + Normal.ToString();
	sprintf(val, " D:%#f}", D); temp += val;

	return temp;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 
///@param 
//////////////////////////////////////////////////////////////////////////
D3DXPLANE Plane::ToD3DXPLANE()
{
	return D3DXPLANE(Normal.X, Normal.Y, Normal.Z, D);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 정규화
//////////////////////////////////////////////////////////////////////////
void Plane::Normalize()
{
	float num1 = (float)((double)Normal.X * (double)Normal.X + (double)Normal.Y * (double)Normal.Y + (double)Normal.Z * (double)Normal.Z);
	
	if((double)MathHelper::Abs(num1 - 1.0f) >= 1.19209289550781E-07)
	{
		float num2 = 1.0f / (float)sqrt((double)num1);
		Normal.X *= num2;
		Normal.Y *= num2;
		Normal.Z *= num2;
		D *= num2;
	}
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 정규화
///@param value : 평면
///@return 결과 평면
//////////////////////////////////////////////////////////////////////////
Plane Plane::Normalize( Plane value )
{
	float num1 = (float)((double)value.Normal.X * (double)value.Normal.X + (double)value.Normal.Y * (double)value.Normal.Y + (double)value.Normal.Z * (double)value.Normal.Z);

	if((double)MathHelper::Abs(num1 - 1.0f) < 1.19209289550781E-07)
	{
		Plane plane;
		plane.Normal = value.Normal;
		plane.D = value.D;

		return plane;
	}
	else
	{
		float num2 = 1.0f / (float)sqrt((double)num1);
		
		Plane plane;
		plane.Normal.X = value.Normal.X * num2;
		plane.Normal.Y = value.Normal.Y * num2;
		plane.Normal.Z = value.Normal.Z * num2;
		plane.D = value.D * num2;

		return plane;
	}
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 매트릭스에 의한 평면 변환
///@param plane : 평면
///@param matrix : 매트릭스
///@return 결과 평면
//////////////////////////////////////////////////////////////////////////
Plane Plane::Transform( Plane plane, Matrix matrix )
{
	Matrix result;
	result = Matrix::Invert(matrix);

	Plane plane1;
	plane1.Normal.X = (float)((double)plane.Normal.X * (double)result.M11 + (double)plane.Normal.Y * (double)result.M12 + (double)plane.Normal.Z * (double)result.M13 + (double)plane.D * (double)result.M14);
	plane1.Normal.Y = (float)((double)plane.Normal.X * (double)result.M21 + (double)plane.Normal.Y * (double)result.M22 + (double)plane.Normal.Z * (double)result.M23 + (double)plane.D * (double)result.M24);
	plane1.Normal.Z = (float)((double)plane.Normal.X * (double)result.M31 + (double)plane.Normal.Y * (double)result.M32 + (double)plane.Normal.Z * (double)result.M33 + (double)plane.D * (double)result.M34);
	plane1.D = (float)((double)plane.Normal.X * (double)result.M41 + (double)plane.Normal.Y * (double)result.M42 + (double)plane.Normal.Z * (double)result.M43 + (double)plane.D * (double)result.M44);

	return plane1;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 쿼터니온에 의한 평면 변환
///@param plane : 평면
///@param rotation : 쿼터니온
///@return 결과 평면
//////////////////////////////////////////////////////////////////////////
Plane Plane::Transform( Plane plane, Quaternion rotation )
{
	float wxx = rotation.W * (rotation.X + rotation.X);
	float wyy = rotation.W * (rotation.Y + rotation.Y);
	float wzz = rotation.W * (rotation.Z + rotation.Z);

	float xxx = rotation.X * (rotation.X + rotation.X);
	float xyy = rotation.X * (rotation.Y + rotation.Y);
	float xzz = rotation.X * (rotation.Z + rotation.Z);

	float yyy = rotation.Y * (rotation.Y + rotation.Y);
	float yzz = rotation.Y * (rotation.Z + rotation.Z);
	float zzz = rotation.Z * (rotation.Z + rotation.Z);

	float num1 = 1.0f - yyy - zzz;
	float num2 = xyy - wzz;
	float num3 = xzz + wyy;
	float num4 = xyy + wzz;

	float num5 = 1.0f - xxx - zzz;
	float num6 = yzz - wxx;
	float num7 = xzz - wyy;
	float num8 = yzz + wxx;

	float num9 = 1.0f - xxx - yyy;
	float num10 = plane.Normal.X;
	float num11 = plane.Normal.Y;
	float num12 = plane.Normal.Z;

	Plane plane1;
	plane1.Normal.X = (float)((double)num10 * (double)num1 + (double)num11 * (double)num2 + (double)num12 * (double)num3);
	plane1.Normal.Y = (float)((double)num10 * (double)num4 + (double)num11 * (double)num5 + (double)num12 * (double)num6);
	plane1.Normal.Z = (float)((double)num10 * (double)num7 + (double)num11 * (double)num8 + (double)num12 * (double)num9);
	plane1.D = plane.D;
	
	return plane1;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 평면과 4D 벡터의 내적
///@param value : 벡터
///@return 결과 값
//////////////////////////////////////////////////////////////////////////
float Plane::Dot( Vector4 value )
{
	return (float)((double)Normal.X * (double)value.X + (double)Normal.Y * (double)value.Y + (double)Normal.Z * (double)value.Z + (double)D * (double)value.W);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 평면과 3D 위치 벡터의 내적(W=1.0f)
///@param value : 벡터
///@return 결과 값
//////////////////////////////////////////////////////////////////////////
float Plane::DotCoordinate( Vector3 value )
{
	return (float)((double)Normal.X * (double)value.X + (double)Normal.Y * (double)value.Y + (double)Normal.Z * (double)value.Z)+ D;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 평면과 3D 방향 벡터의 내적(W=0.0f)
///@param value : 벡터
///@return 결과 값
//////////////////////////////////////////////////////////////////////////
float Plane::DotNormal( Vector3 value )
{
	return (float)((double)Normal.X * (double)value.X + (double)Normal.Y * (double)value.Y + (double)Normal.Z * (double)value.Z);
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 박스와의 교차 검사
///@param box : 바운딩 박스
///@return 교차 결과
//////////////////////////////////////////////////////////////////////////
PlaneIntersectionType Plane::Intersects(BoundingBox box)
{
	Vector3 vector3_1;
	vector3_1.X = (double)Normal.X >= 0.0 ? box.Min.X : box.Max.X;
	vector3_1.Y = (double)Normal.Y >= 0.0 ? box.Min.Y : box.Max.Y;
	vector3_1.Z = (double)Normal.Z >= 0.0 ? box.Min.Z : box.Max.Z;

	Vector3 vector3_2;
	vector3_2.X = (double)Normal.X >= 0.0 ? box.Max.X : box.Min.X;
	vector3_2.Y = (double)Normal.Y >= 0.0 ? box.Max.Y : box.Min.Y;
	vector3_2.Z = (double)Normal.Z >= 0.0 ? box.Max.Z : box.Min.Z;

	if((double)Normal.X * (double)vector3_1.X + (double)Normal.Y * (double)vector3_1.Y + (double)Normal.Z * (double)vector3_1.Z + (double)D > 0.0)
		return PlaneIntersectionType_Front;
	else if ((double)Normal.X * (double)vector3_2.X + (double)Normal.Y * (double)vector3_2.Y + (double)Normal.Z * (double)vector3_2.Z + (double)D < 0.0)
		return PlaneIntersectionType_Back;
	else
		return PlaneIntersectionType_Intersecting;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 프러스텀과의 교차검사
///@param frustum : 바운딩 프러스텀
///@return 교차 결과
//////////////////////////////////////////////////////////////////////////
PlaneIntersectionType Plane::Intersects( BoundingFrustum frustum )
{
	PlaneIntersectionType result;
	frustum.Intersects(*this, result);

	return result;
}
//////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////
///@brief 바운딩 스페어와의 교차검사
///@param sphere : 바운딩 스페어
///@return 교차 결과
//////////////////////////////////////////////////////////////////////////
PlaneIntersectionType Plane::Intersects( BoundingSphere sphere )
{
	float num = (float)((double)sphere.Center.X * (double)Normal.X + (double)sphere.Center.Y * (double)Normal.Y + (double)sphere.Center.Z * (double)Normal.Z) + D;
	
	if ((double)num > (double)sphere.Radius)
		return PlaneIntersectionType_Front;
	else if ((double)num < -(double)sphere.Radius)
		return PlaneIntersectionType_Back;
	else
		return PlaneIntersectionType_Intersecting;	
}<file_sep>#include "stdafx.h"
#include "ExportMesh.h"
#include "./Fbx/Exporter.h"

ExportMesh::ExportMesh(ExecuteValues* values)
	: Execute(values)
{
	Fbx::Exporter* exporter = NULL;

	//Grund
	exporter = new Fbx::Exporter(Assets + L"Grund/Grund.fbx", true);
	exporter->ExportMaterial(Models + L"Grund/", L"Grund");
	exporter->ExportMeshData(Models + L"Grund/", L"Grund");
	SAFE_DELETE(exporter);

	//France
	/*exporter = new Fbx::Exporter(Assets + L"Map/Stage1/France.fbx");
	exporter->ExportMaterial(Models + L"Stage1/", L"France");
	exporter->ExportMeshData(Models + L"Stage1/", L"France");
	SAFE_DELETE(exporter);*/

	//France_Sky
	/*exporter = new Fbx::Exporter(Assets + L"Map/Stage1/France_Sky.fbx");
	exporter->ExportMaterial(Models + L"Stage1/", L"France_Sky");
	exporter->ExportMeshData(Models + L"Stage1/", L"France_Sky");
	SAFE_DELETE(exporter);*/
}

ExportMesh::~ExportMesh()
{
	
}

void ExportMesh::Update()
{
	
}

void ExportMesh::Render()
{
	
}

void ExportMesh::PostRender()
{

}
<file_sep>#include "stdafx.h"
#include "DrawModel.h"
#include "../Objects/GameSkyBox.h"
#include "../Objects/GameWorld.h"
#include "../Objects/GameAnimationModel.h"
#include "../Units/GamePlayer.h"

DrawModel::DrawModel(ExecuteValues* values)
	: Execute(values)
	, skyBox(NULL), world(NULL), grund(NULL)
	, player(NULL)
{
	CreateEnvironment();
	//CreateAnimationModel();
	CreatePlayer();
}

DrawModel::~DrawModel()
{
	SAFE_DELETE(player);
	SAFE_DELETE(grund);
	SAFE_DELETE(world);
	SAFE_DELETE(skyBox);
}

void DrawModel::Update()
{
	if (skyBox != NULL) skyBox->Update();
	if (world != NULL) world->Update();
	if (grund != NULL) grund->Update();
	if (player != NULL) player->Update();
}

void DrawModel::Render()
{
	if (skyBox != NULL) skyBox->Render();
	if (world != NULL) world->Render();
	if (grund != NULL) grund->Render();
	if (player != NULL) player->Render();
}

void DrawModel::PostRender()
{
	if (values->GuiSettings->bShowModelWindow == true)
	{
		ImGui::Begin("Model Info", &values->GuiSettings->bShowModelWindow);
		int boneCount;
		boneCount = player->GetModel()->BoneCount();
		vector<string> boneNames;

		for (int i = 0; i < boneCount; i++)
		{
			boneNames.push_back(String::ToString(player->GetModel()->Bone(i)->Name()));
		}
		
		static const char* current_Clip = NULL;
		if (ImGui::BeginCombo("Anim Clip", current_Clip)) // The second parameter is the label previewed before opening the combo.
		{
			for (int n = 0; n < boneNames.size(); n++)
			{
				bool is_selected = (current_Clip == boneNames[n].c_str()); // You can store your selection however you want, outside or inside your objects
				if (ImGui::Selectable(boneNames[n].c_str(), is_selected))
					current_Clip = boneNames[n].c_str();
				if (is_selected)
					ImGui::SetItemDefaultFocus();   // Set the initial focus when opening the combo (scrolling + for keyboard navigation support in the upcoming navigation branch)
			}
			ImGui::EndCombo();
		}

		if (current_Clip != NULL)
		{

		}
		
		

		ImGui::End();
	}
}

void DrawModel::CreateEnvironment()
{
	wstring matFile = L"";
	wstring meshFile = L"";

	//World
	matFile = Models + L"Stage1/France.material";
	meshFile = Models + L"Stage1/France.mesh";
	world = new GameWorld(matFile, meshFile);

	//SkyBox
	matFile = Models + L"Stage1/France_Sky.material";
	meshFile = Models + L"Stage1/France_Sky.mesh";
	skyBox = new GameSkyBox(matFile, meshFile);
	skyBox->Position(D3DXVECTOR3(0, 20, 0));
}

void DrawModel::CreateAnimationModel()
{
	wstring matFile = L"";
	wstring meshFile = L"";

	//Grund
	matFile = Models + L"Grund/Grund.material";
	meshFile = Models + L"Grund/Grund.mesh";
	grund = new GameAnimationModel(matFile, meshFile);

	grund->AddClip(Models + L"Grund/Low_Idle.anim");
	grund->AddClip(Models + L"Grund/Up_Idle.anim");
	grund->AddClip(Models + L"Grund/Low_Run.anim");
	grund->AddClip(Models + L"Grund/Up_Run.anim");
	grund->AddClip(Models + L"Grund/Up_AttackFrontBase.anim");

	grund->Play(0, 0, 0, 1, AnimationPlayMode::Repeat);
	grund->Play(1, 0, 0, 1, AnimationPlayMode::Repeat);
}

void DrawModel::CreatePlayer()
{
	wstring matFile = L"";
	wstring meshFile = L"";

	//Grund
	matFile = Models + L"Grund/Grund.material";
	meshFile = Models + L"Grund/Grund.mesh";
	player = new GamePlayer(Models + L"Grund/", matFile, meshFile);
}
<file_sep>#pragma once

#include "Gjk.h"
#include "../Core/Vector3.h"
#include "../Core/Matrix.h"
#include "../Core/Plane.h"

enum PlaneIntersectionType;
enum ContainmentType;

class Ray;
class BoundingBox;
class BoundingSphere;

//////////////////////////////////////////////////////////////////////////
///@brief 충돌 프러스텀
//////////////////////////////////////////////////////////////////////////
class BoundingFrustum
{
public:
	BoundingFrustum(void);
	BoundingFrustum(Matrix value);

	bool operator ==(const BoundingFrustum& value) const;
	bool operator !=(const BoundingFrustum& value) const;
	bool Equals(const BoundingFrustum& value) const;

	std::string ToString();

	Vector3 SupportMapping(Vector3 v);

	Plane Near() const;
	Plane Far() const;
	Plane Left() const;
	Plane Right() const;
	Plane Top() const;
	Plane Bottom() const;

	Matrix GetMatrix() const;
	void SetMatrix(const Matrix value);

	void GetCorner(Vector3* pCorner);

	static Ray ComputeIntersectionLine(Plane p1, Plane p2);
	static Vector3 ComputeIntersection(Plane plane, Ray ray);

	bool Intersects(BoundingBox box);
	void Intersects(BoundingBox box, bool& result);
	bool Intersects(BoundingFrustum frustum);
	void Intersects(Plane plane, PlaneIntersectionType& result);
	void Intersects(Ray ray, float* result);
	bool Intersects(BoundingSphere sphere);
	void Intersects(BoundingSphere sphere, bool& result);

	ContainmentType Contains(BoundingBox box);
	ContainmentType Contains(BoundingFrustum frustum);
	ContainmentType Contains(Vector3 point);
	ContainmentType Contains(BoundingSphere sphere);

public:
	const static int CornerCount;
	const static int NearPlaneIndex;
	const static int FarPlaneIndex;
	const static int LeftPlaneIndex;
	const static int RightPlaneIndex;
	const static int TopPlaneIndex;
	const static int BottomPlaneIndex;
	const static int NumPlanes;

	Plane planes[6];
	Vector3 cornerArray[8];
	Matrix matrix;
	Gjk gjk;
};<file_sep>#pragma once

class DrawModel : public Execute
{
public:
	DrawModel(ExecuteValues* values);
	~DrawModel();

	void Update();

	void PreRender() {}
	void Render();
	void PostRender();

	void ResizeScreen() {}

private:
	void CreateEnvironment();
	void CreateAnimationModel();
	void CreatePlayer();

private:
	class GameSkyBox* skyBox;
	class GameWorld* world;
	class GameAnimationModel* grund;
	class GamePlayer* player;
};