game2006/server/gameserver/mt/MapCollider.cc
aozhiwei e1f0817c8d 1
2023-06-29 20:26:36 +08:00

139 lines
4.3 KiB
C++

#include "precompile.h"
#include <a8/xobject.h>
#include <f8/udplog.h>
#include "mt/MapCollider.h"
#include "mt/MetaMgr.h"
#include "navmesh.pb.h"
std::vector<mt::MapCollider*> mt::MapCollider::raw_list;
std::map<std::string, mt::MapCollider*> mt::MapCollider::name_hash;
namespace mt
{
MapCollider* MapCollider::GetByName(const std::string& name)
{
auto itr = name_hash.find(name);
return itr != name_hash.end() ? itr->second : nullptr;
}
void MapCollider::StaticPostInit()
{
}
void MapCollider::LoadAll()
{
#if 0
std::vector<std::string> files = {
"main3d_map.colliders.json"
};
for (auto& filename : files) {
MapCollider* p = new MapCollider();
p->Load(filename);
p->LoadTerrain("map4_terrain.bin");
raw_list.push_back(p);
name_hash[filename] = p;
}
#endif
}
void MapCollider::Load(const std::string& filename)
{
a8::XObject xobj_root;
xobj_root.ReadFromFile(MetaMgr::Instance()->GetResDir() + filename);
auto xobj_nodes = xobj_root.At("nodes");
for (int i = 0; i < xobj_nodes->Size(); ++i) {
auto xobj_node = xobj_nodes->At(i);
mc::ColliderNode* node = new mc::ColliderNode();
node->Read(xobj_node);
if (nodes_.find(node->name) != nodes_.end()) {
abort();
}
nodes_[node->name] = node;
}
}
void MapCollider::LoadTerrain(const std::string& filename)
{
navmesh::vertex verts_pb;
long long begin_tick = a8::XGetTickCount();
FILE *fp = fopen((mt::MetaMgr::Instance()->GetResDir() + filename).c_str(), "rb");
if (fp) {
fseek(fp, 0, SEEK_END);
int file_size = ftell(fp);
if (file_size > 0) {
fseek(fp, 0, SEEK_SET);
char* data = (char*)malloc(file_size);
size_t read_len = fread(data, file_size, 1, fp);
bool ok = verts_pb.ParseFromArray(data, file_size);
if (!ok) {
abort();
}
free(data);
}
fclose(fp);
}
if (verts_pb.triangles().size() <= 0) {
abort();
}
const std::string terrain_name = "_terrain_";
mc::ColliderNode* node = new mc::ColliderNode();
node->name = terrain_name;
if (nodes_.find(node->name) != nodes_.end()) {
abort();
}
{
mc::MeshCollider* mesh = new mc::MeshCollider();
mesh->type = mc::kMeshCollider;
mesh->ca_type = mc::kCA_Surface;
mesh->mesh.vertices.reserve(verts_pb.vectors().size());
for (auto v : verts_pb.vectors()) {
mesh->mesh.vertices.push_back
(
glm::vec3(v.x() * mc::MAP_SCALE,
v.y(),
v.z() * mc::MAP_SCALE)
);
}
mesh->mesh.raw_triangles.reserve(verts_pb.triangles().size());
for (auto t : verts_pb.triangles()) {
mesh->mesh.raw_triangles.push_back
(
t
);
}
node->colliders.push_back(mesh);
}
nodes_[node->name] = node;
long long end_tick = a8::XGetTickCount();
f8::UdpLog::Instance()->Info("load terrain file_name:%s triangles:%d vectors:%d cost_time:%d",
{
filename,
verts_pb.triangles().size(),
verts_pb.vectors().size(),
end_tick - begin_tick
});
SaveToObjFile("1.obj", verts_pb);
}
void MapCollider::SaveToObjFile(const std::string& filename, const navmesh::vertex& verts_pb)
{
for (auto v : verts_pb.vectors()) {
}
for (auto t : verts_pb.triangles()) {
}
}
mc::ColliderNode* MapCollider::GetNode(const std::string& name)
{
auto itr = nodes_.find(name);
return itr != nodes_.end() ? itr->second : nullptr;
}
}