Files
Leviathan/Client/Game/game/Utility/PropRespawnRegionExtractor.h
2026-06-01 12:46:52 +02:00

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