224 lines
4.5 KiB
C++
224 lines
4.5 KiB
C++
|
|
#ifndef _PropRespawnRegionExtractor_h_
|
|
#define _PropRespawnRegionExtractor_h_
|
|
|
|
#include "KTypes.h"
|
|
#include <map>
|
|
//#include <vector>
|
|
|
|
class cPropRespawnRegionExtractor
|
|
{
|
|
private:
|
|
/*
|
|
/// qpf 파일을 읽어서 갖고온 데이타들
|
|
*/
|
|
struct sPropData
|
|
{
|
|
sPropData() {}
|
|
~sPropData()
|
|
{
|
|
m_itemList.clear();
|
|
m_posList.clear();
|
|
}
|
|
sPropData(int propId, float x, float y)
|
|
{
|
|
m_propId = propId;
|
|
addPos(x, y);
|
|
}
|
|
void addPos(float x, float y)
|
|
{
|
|
m_posList.push_back(KPoint((int)x, (int)y));
|
|
}
|
|
int m_propId;
|
|
std::vector<int> m_itemList;
|
|
std::vector<KPoint> m_posList;
|
|
};
|
|
typedef map<int, sPropData> map_prop;
|
|
/*
|
|
*/
|
|
struct sItemData
|
|
{
|
|
sItemData() {}
|
|
sItemData(int itemId, std::vector<KPoint> const& posList)
|
|
{
|
|
m_itemId = itemId;
|
|
m_posList = posList;
|
|
}
|
|
~sItemData()
|
|
{
|
|
m_posList.clear();
|
|
}
|
|
void addPos(std::vector<KPoint> const& posList)
|
|
{
|
|
m_posList.insert(m_posList.end(), posList.begin(), posList.end());
|
|
}
|
|
|
|
int m_itemId;
|
|
std::vector<KPoint> m_posList;
|
|
};
|
|
typedef map<int, sItemData> map_item;
|
|
/*
|
|
*/
|
|
struct sItemGroupData
|
|
{
|
|
struct sGroup
|
|
{
|
|
~sGroup()
|
|
{
|
|
m_posList.clear();
|
|
}
|
|
void addPos(KPoint const& pos)
|
|
{
|
|
m_posList.push_back(pos);
|
|
}
|
|
void makeRect(int w, int h)
|
|
{
|
|
/// group의 중심을 구한다
|
|
KPoint center(0, 0);
|
|
std::vector<KPoint>::iterator it = m_posList.begin();
|
|
for (; it != m_posList.end(); ++it)
|
|
{
|
|
center.x += it->x;
|
|
center.y += it->y;
|
|
}
|
|
center.x /= (int)m_posList.size();
|
|
center.y /= (int)m_posList.size();
|
|
|
|
int hw = w >> 1;
|
|
int hh = h >> 1;
|
|
|
|
m_rect.left = center.x - hw;
|
|
m_rect.top = center.y - hh;
|
|
m_rect.right = center.x + hw;
|
|
m_rect.bottom = center.y += hh;
|
|
}
|
|
|
|
std::vector<KPoint> m_posList;
|
|
/// 최종 결과
|
|
float m_theta;
|
|
KRect m_rect;
|
|
};
|
|
|
|
~sItemGroupData() { m_groupList.clear(); }
|
|
|
|
int m_itemId;
|
|
std::vector<sGroup> m_groupList;
|
|
};
|
|
typedef map<int, sItemGroupData> map_itemGroup;
|
|
/*
|
|
*/
|
|
struct sCorMatrix
|
|
{
|
|
private:
|
|
struct sCenter
|
|
{
|
|
sCenter() {}
|
|
sCenter(float x, float y) { v[0] = x; v[1] = y; }
|
|
float v[2];
|
|
};
|
|
|
|
public:
|
|
void make(std::vector<KPoint> const& posList)
|
|
{
|
|
// 중점
|
|
std::vector<sCenter> centerList;
|
|
makeCenter(posList, centerList);
|
|
// 평균
|
|
float ave[2];
|
|
makeAverage(centerList, ave);
|
|
|
|
float x_ij, x_ik;
|
|
int n = centerList.size();
|
|
float f_n = (float)n;
|
|
for (int j = 0; j < 2; ++j)
|
|
{
|
|
for (int k = 0; k < 2; ++k)
|
|
{
|
|
float value = 0;
|
|
for (int i = 0; i < n; ++i)
|
|
{
|
|
x_ij = centerList[i].v[j];
|
|
x_ik = centerList[i].v[k];
|
|
value += (x_ij - ave[j]) * (x_ik - ave[k]);
|
|
}
|
|
value /= f_n;
|
|
v[j][k] = value;
|
|
}
|
|
}
|
|
|
|
centerList.clear();
|
|
}
|
|
|
|
private:
|
|
void makeAverage(std::vector<sCenter> const& centerList, float* ave)
|
|
{
|
|
float _ave[2] = {0.0f, 0.0f};
|
|
int n = centerList.size();
|
|
for (int i = 0; i < n; ++i)
|
|
{
|
|
_ave[0] += centerList[i].v[0];
|
|
_ave[1] += centerList[i].v[1];
|
|
}
|
|
|
|
_ave[0] /= (float)n;
|
|
_ave[1] /= (float)n;
|
|
|
|
ave[0] = _ave[0];
|
|
ave[1] = _ave[1];
|
|
};
|
|
void makeCenter(std::vector<KPoint> const& pointList, std::vector<sCenter>& centerList)
|
|
{
|
|
std::vector<KPoint>::const_iterator it = pointList.begin();
|
|
for (; it != pointList.end(); ++it)
|
|
{
|
|
centerList.push_back(sCenter((float)it->x, (float)it->y));
|
|
}
|
|
}
|
|
|
|
public:
|
|
float v[2][2];
|
|
};
|
|
|
|
public:
|
|
struct sItemRegionRect
|
|
{
|
|
KRect m_rect;
|
|
float m_theta;
|
|
};
|
|
struct sItemRegion
|
|
{
|
|
typedef std::vector<sItemRegionRect>::iterator it_region;
|
|
|
|
~sItemRegion() { m_regionList.clear(); }
|
|
int m_itemId;
|
|
std::vector<sItemRegionRect> m_regionList;
|
|
};
|
|
|
|
public:
|
|
cPropRespawnRegionExtractor();
|
|
~cPropRespawnRegionExtractor();
|
|
|
|
void extract();
|
|
bool readData(char const* filename, std::map<int, sItemRegion>& itemRegionList);
|
|
|
|
private:
|
|
bool getSeamlessWorldInfo();
|
|
bool extractQpf(map_prop& propList);
|
|
void grouping(map_itemGroup& itemGroupList, int groupLength);
|
|
int getPointLength(KPoint const& p1, KPoint const& p2);
|
|
void calcCovariance(map_itemGroup& itemGroupList);
|
|
bool writeData(char const* filename, map_itemGroup const& itemGroupList);
|
|
/// propList를 itemList로 바꿔준다
|
|
void convertPropToItem(map_prop const& propList);
|
|
/// propList에 있는 itemList의 정보를 채운다
|
|
void setItemAtPropList(map_prop& propList);
|
|
|
|
private:
|
|
int m_segmentCountPerMap;
|
|
int m_tileCountPerSegment;
|
|
int m_tileCountPerMap;
|
|
float m_tileLength;
|
|
map_item m_itemList;
|
|
};
|
|
|
|
#endif |