void ResourceManager::Init()
{
    AddMesh( MODEL_UNIT_SWORD, MESH_KEY_UNIT_SWORD );
    AddMesh( MODEL_UNIT_PIKE, MESH_KEY_UNIT_PIKE );
    AddMesh( MODEL_UNIT_ARROW, MESH_KEY_UNIT_ARROW );
    AddMesh( MODEL_UNIT_KNIGHT, MESH_KEY_UNIT_KNIGHT );
    AddMesh( MODEL_UNIT_GUARD, MESH_KEY_UNIT_GUARD );
    AddMesh( MODEL_UNIT_KING, MESH_KEY_UNIT_KING );

    AddMesh( MODEL_CORPS_DESTROY_A, MESH_KEY_CORPS_DESTROY_ENEMY );
    AddMesh( MODEL_CORPS_DEFENSE_A, MESH_KEY_CORPS_DEFENSE_ENEMY );
    AddMesh( MODEL_CORPS_RUSH_A, MESH_KEY_CORPS_RUSH_ENEMY );
    AddMesh( MODEL_CORPS_DESTROY_B, MESH_KEY_CORPS_DESTROY_MINE );
    AddMesh( MODEL_CORPS_DEFENSE_B, MESH_KEY_CORPS_DEFENSE_MINE );
    AddMesh( MODEL_CORPS_RUSH_B, MESH_KEY_CORPS_RUSH_MINE );

    AddMap( HEIGHT_MAP, HEIGHT_TEX, MAP_KEY_TEST );
    CreateMap( MAP_KEY_TEST );

    //////////////////////////////////////////////////////////////////////////
    // 쿼드트리를 적용하기 위해 하이트 맵은 2^n 형태의 크기로 만들어야 합니다.
    //
    // 주의! 실제 하이트맵 크기는 한 변이 2^n + 1 사이즈여야 합니다!
    //////////////////////////////////////////////////////////////////////////
    InitGroundMesh( 128, 128 );
    CreateRawGround( 128, 128, 5.0f );

    if ( FAILED( InitHeightMap( HEIGHT_MAP, 5.0f ) ) )
    {
        m_IsMapForQuadTreeReady = false;
    }
    else
    {
        m_IsMapForQuadTreeReady = true;
    }

    MapManager::GetInstance()->SetPixelSize( 5.0f );

    m_MapSize = 640;
    m_IsMapReady = true;

    InitSkyBoxMesh( 640 );

    SetSkyBoxTexture( SPRITE_SKYBOX_BACK, SKY_BOX_BACK );
    SetSkyBoxTexture( SPRITE_SKYBOX_FRONT, SKY_BOX_FRONT );
    SetSkyBoxTexture( SPRITE_SKYBOX_LEFT, SKY_BOX_LEFT );
    SetSkyBoxTexture( SPRITE_SKYBOX_RIGHT, SKY_BOX_RIGHT );
    SetSkyBoxTexture( SPRITE_SKYBOX_TOP, SKY_BOX_TOP );
    SetSkyBoxTexture( SPRITE_SKYBOX_BOTTOM, SKY_BOX_BOTTOM );

    InitCursor( CURSOR_MAX, MouseManager::GetInstance()->GetMousePositionX(), MouseManager::GetInstance()->GetMousePositionY() );
    CreateCursorImage( SPRITE_CURSOR_DEFAULT, CURSOR_DEFAULT );
    CreateCursorImage( SPRITE_CURSOR_ATTACK, CURSOR_ATTACK );
    CreateCursorImage( SPRITE_CURSOR_CLICK, CURSOR_CLICK );
    CreateCursorImage( SPRITE_CURSOR_OVER_CORPS, CURSOR_OVER_CORPS );
    CreateCursorImage( SPRITE_CURSOR_UNRECHEABLE, CURSOR_UNRECHEABLE );
    CreateCursorImage( SPRITE_CURSOR_CAMERA_ROTATING, CURSOR_CAMERA_ROTATING );
    CreateCursorImage( SPRITE_CURSOR_CORPS_MOVABLE, CURSOR_CORPS_MOVABLE );
    CreateCursorImage( SPRITE_CURSOR_CORPS_MOVABLE_CLICK, CURSOR_CORPS_MOVABLE_CLICK );
    CreateCursorImage( SPRITE_CURSOR_OVER_PICKED_CORPS, CURSOR_OVER_PICKED_CORPS );

    m_ISCursorReady = true;

    CreateSprite();

    ShaderCreate( SHADER_TYPE_MAX );
    ShaderImport( SELECT_SHADER, SHADER_SELECT );
    ShaderImport( FIGHT_SHADER, SHADER_FIGHT );
    ShaderImport( MAP_SHADER, SHADER_MAP );

    MeshTextureCreateBySize( CORPS_TEXTURE_MAX );
    MeshTextureImport( SPRITE_CORPS_TYPE_ARROW, CORPS_TEXTURE_ARROW );
    MeshTextureImport( SPRITE_CORPS_TYPE_GUARD, CORPS_TEXTURE_GUARD );
    MeshTextureImport( SPRITE_CORPS_TYPE_KING, CORPS_TEXTURE_KING );
    MeshTextureImport( SPRITE_CORPS_TYPE_KNIGHT, CORPS_TEXTURE_KNIGHT );
    MeshTextureImport( SPRITE_CORPS_TYPE_PIKE, CORPS_TEXTURE_PIKE );
    MeshTextureImport( SPRITE_CORPS_TYPE_SWORD, CORPS_TEXTURE_SWORD );
}
UVaOceanSimulatorComponent::UVaOceanSimulatorComponent(const class FPostConstructInitializeProperties& PCIP)
: Super(PCIP)
{
	bAutoActivate = true;
	PrimaryComponentTick.bCanEverTick = true;
	//PrimaryComponentTick.TickGroup = TG_DuringPhysics;

	// Vertex to draw on render targets
	m_pQuadVB[0].Set(-1.0f, -1.0f, 0.0f, 1.0f);
	m_pQuadVB[1].Set(-1.0f,  1.0f, 0.0f, 1.0f);
	m_pQuadVB[2].Set( 1.0f, -1.0f, 0.0f, 1.0f);
	m_pQuadVB[3].Set( 1.0f,  1.0f, 0.0f, 1.0f);

	// Cache shader immutable parameters (looks ugly, but nicely used then)
	UpdateSpectrumCSImmutableParams.g_ActualDim = OceanConfig.DispMapDimension;
	UpdateSpectrumCSImmutableParams.g_InWidth = UpdateSpectrumCSImmutableParams.g_ActualDim + 4;
	UpdateSpectrumCSImmutableParams.g_OutWidth = UpdateSpectrumCSImmutableParams.g_ActualDim;
	UpdateSpectrumCSImmutableParams.g_OutHeight = UpdateSpectrumCSImmutableParams.g_ActualDim;
	UpdateSpectrumCSImmutableParams.g_DtxAddressOffset = FMath::Square(UpdateSpectrumCSImmutableParams.g_ActualDim);
	UpdateSpectrumCSImmutableParams.g_DtyAddressOffset = FMath::Square(UpdateSpectrumCSImmutableParams.g_ActualDim) * 2;

	// Height map H(0)
	int32 height_map_size = (OceanConfig.DispMapDimension + 4) * (OceanConfig.DispMapDimension + 1);
	TResourceArray<FVector2D> h0_data;
	h0_data.Init(FVector2D::ZeroVector, height_map_size);
	TResourceArray<float> omega_data;
	omega_data.Init(0.0f, height_map_size);
	InitHeightMap(OceanConfig, h0_data, omega_data);

	int hmap_dim = OceanConfig.DispMapDimension;
	int input_full_size = (hmap_dim + 4) * (hmap_dim + 1);
	// This value should be (hmap_dim / 2 + 1) * hmap_dim, but we use full sized buffer here for simplicity.
	int input_half_size = hmap_dim * hmap_dim;
	int output_size = hmap_dim * hmap_dim;

	// For filling the buffer with zeroes
	TResourceArray<float> zero_data;
	zero_data.Init(0.0f, 3 * output_size * 2);

	// RW buffer allocations
	// H0
	uint32 float2_stride = 2 * sizeof(float);
	CreateBufferAndUAV(&h0_data, input_full_size * float2_stride, float2_stride, &m_pBuffer_Float2_H0, &m_pUAV_H0, &m_pSRV_H0);

	// Notice: The following 3 buffers should be half sized buffer because of conjugate symmetric input. But
	// we use full sized buffers due to the CS4.0 restriction.

	// Put H(t), Dx(t) and Dy(t) into one buffer because CS4.0 allows only 1 UAV at a time
	CreateBufferAndUAV(&zero_data, 3 * input_half_size * float2_stride, float2_stride, &m_pBuffer_Float2_Ht, &m_pUAV_Ht, &m_pSRV_Ht);

	// omega
	CreateBufferAndUAV(&omega_data, input_full_size * sizeof(float), sizeof(float), &m_pBuffer_Float_Omega, &m_pUAV_Omega, &m_pSRV_Omega);

	// Re-init the array because it was discarded by previous buffer creation
	zero_data.Empty();
	zero_data.Init(0.0f, 3 * output_size * 2);
	// Notice: The following 3 should be real number data. But here we use the complex numbers and C2C FFT
	// due to the CS4.0 restriction.
	// Put Dz, Dx and Dy into one buffer because CS4.0 allows only 1 UAV at a time
	CreateBufferAndUAV(&zero_data, 3 * output_size * float2_stride, float2_stride, &m_pBuffer_Float_Dxyz, &m_pUAV_Dxyz, &m_pSRV_Dxyz);

	// FFT
	RadixCreatePlan(&FFTPlan, 3);
}