mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 05:21:29 +00:00
Zone MMF Implementation (for map files)
This commit is contained in:
parent
345f3d6301
commit
84db0ec2c5
@ -30,6 +30,7 @@
|
|||||||
#EQEMU_BUILD_LUA
|
#EQEMU_BUILD_LUA
|
||||||
#EQEMU_SANITIZE_LUA_LIBS
|
#EQEMU_SANITIZE_LUA_LIBS
|
||||||
#EQEMU_BUILD_CLIENT_FILES
|
#EQEMU_BUILD_CLIENT_FILES
|
||||||
|
#EQEMU_USE_MAP_MMFS
|
||||||
#EQEMU_MAP_DIR
|
#EQEMU_MAP_DIR
|
||||||
|
|
||||||
#We set a fairly new version (as of 2013) because I found finding perl was a bit... buggy on older ones
|
#We set a fairly new version (as of 2013) because I found finding perl was a bit... buggy on older ones
|
||||||
@ -275,6 +276,11 @@ IF(EQEMU_BUILD_LUA)
|
|||||||
ADD_DEFINITIONS(-DLUA_EQEMU)
|
ADD_DEFINITIONS(-DLUA_EQEMU)
|
||||||
ENDIF(EQEMU_BUILD_LUA)
|
ENDIF(EQEMU_BUILD_LUA)
|
||||||
|
|
||||||
|
OPTION(EQEMU_USE_MAP_MMFS "Create and use Zone Map MMF files." OFF)
|
||||||
|
IF(EQEMU_USE_MAP_MMFS)
|
||||||
|
ADD_DEFINITIONS(-DUSE_MAP_MMFS)
|
||||||
|
ENDIF(EQEMU_USE_MAP_MMFS)
|
||||||
|
|
||||||
SET(EQEMU_MAP_DIR "./Maps" CACHE STRING "The dir that maps, water maps, and paths are located in.")
|
SET(EQEMU_MAP_DIR "./Maps" CACHE STRING "The dir that maps, water maps, and paths are located in.")
|
||||||
|
|
||||||
ADD_DEFINITIONS(-DEQDEBUG=${EQEMU_DEBUG_LEVEL})
|
ADD_DEFINITIONS(-DEQDEBUG=${EQEMU_DEBUG_LEVEL})
|
||||||
|
|||||||
@ -1,6 +1,18 @@
|
|||||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
== 07/25/216 ==
|
== 07/28/2016 ==
|
||||||
|
Uleat: Implemented zone memory-mapped file usage
|
||||||
|
- Zone map files are converted to pre-loaded binary files, bypassing the (sometimes) time-consuming raw data transform process
|
||||||
|
- There are three ways to convert files:
|
||||||
|
-- Do nothing! The zone bootup process will check for a mmf file and load it, if found, or create it after the 'normal' transform process is complete
|
||||||
|
-- Use the command line option: zone convert_map <zone_name>.map (for singular conversions)
|
||||||
|
-- Drop the 'convert_maps_to_mmfs.pl' into your server directory and execute it for a batch conversion
|
||||||
|
-- Note: Any zone maps not pre-converted will be processed once a zone is booted up that does not have one
|
||||||
|
- To enable this feature, you must have the 'USE_MAP_MMFS' option checked in cmake and have built binaries on that
|
||||||
|
- To disable this feature, or if you encouter problems, disable the 'USE_MAP_MMFS' option and rebuild your binaries
|
||||||
|
- This feature will test the validity of your zlib library. If you get errors/crashes upon conversion, then your zlib1.dll is most likely suspect (check our forum for solutions)
|
||||||
|
|
||||||
|
== 07/25/2016 ==
|
||||||
mackal: Fix up the SpellBuff struct
|
mackal: Fix up the SpellBuff struct
|
||||||
- THERE MAYBE BUGS
|
- THERE MAYBE BUGS
|
||||||
- there shouldn't though, most of the hackery was from badly named fields causing confusion
|
- there shouldn't though, most of the hackery was from badly named fields causing confusion
|
||||||
|
|||||||
34
utils/scripts/convert_maps_to_mmfs.pl
Normal file
34
utils/scripts/convert_maps_to_mmfs.pl
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
###########################################################
|
||||||
|
#::: Automatic (Map-to-MMF) Conversion Script
|
||||||
|
#::: Author: Uleat
|
||||||
|
#::: Purpose: To convert existing zone maps to memory-mapped files
|
||||||
|
###########################################################
|
||||||
|
|
||||||
|
use Config;
|
||||||
|
|
||||||
|
print("\n");
|
||||||
|
print("Zone Map-to-MMF Batch convertor\n");
|
||||||
|
print("===============================\n");
|
||||||
|
print("\n");
|
||||||
|
|
||||||
|
if($Config{osname}=~/freebsd|linux/i){ $OS = "Linux"; }
|
||||||
|
if($Config{osname}=~/Win|MS/i){ $OS = "Windows"; }
|
||||||
|
print("Operating System is: $Config{osname}\n");
|
||||||
|
print("\n");
|
||||||
|
|
||||||
|
opendir(D, "maps") || die "Can't find directory maps: $!\n";
|
||||||
|
my @mapfiles = grep { /\.map$/ && !/_lit/ } readdir(D);
|
||||||
|
closedir(D);
|
||||||
|
|
||||||
|
foreach my $mapfile (@mapfiles) {
|
||||||
|
my $result = "Unknown action..\n";
|
||||||
|
print("processing map: '$mapfile'\n");
|
||||||
|
if($OS eq "Windows"){ $result = `zone convert_map $mapfile`; }
|
||||||
|
if($OS eq "Linux"){ $result = `./zone convert_map $mapfile`; }
|
||||||
|
print("-- $result");
|
||||||
|
}
|
||||||
|
|
||||||
|
print("\n");
|
||||||
|
print("Batch processing complete\n")
|
||||||
261
zone/map.cpp
261
zone/map.cpp
@ -12,6 +12,48 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
|
|
||||||
|
uint32 EstimateDeflateBuffer(uint32_t len) {
|
||||||
|
z_stream zstream;
|
||||||
|
memset(&zstream, 0, sizeof(zstream));
|
||||||
|
|
||||||
|
zstream.zalloc = Z_NULL;
|
||||||
|
zstream.zfree = Z_NULL;
|
||||||
|
zstream.opaque = Z_NULL;
|
||||||
|
if (deflateInit(&zstream, Z_FINISH) != Z_OK)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return deflateBound(&zstream, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t DeflateData(const char *buffer, uint32_t len, char *out_buffer, uint32_t out_len_max) {
|
||||||
|
z_stream zstream;
|
||||||
|
memset(&zstream, 0, sizeof(zstream));
|
||||||
|
int zerror;
|
||||||
|
|
||||||
|
zstream.next_in = const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(buffer));
|
||||||
|
zstream.avail_in = len;
|
||||||
|
zstream.zalloc = Z_NULL;
|
||||||
|
zstream.zfree = Z_NULL;
|
||||||
|
zstream.opaque = Z_NULL;
|
||||||
|
deflateInit(&zstream, Z_FINISH);
|
||||||
|
|
||||||
|
zstream.next_out = reinterpret_cast<unsigned char*>(out_buffer);
|
||||||
|
zstream.avail_out = out_len_max;
|
||||||
|
zerror = deflate(&zstream, Z_FINISH);
|
||||||
|
|
||||||
|
if (zerror == Z_STREAM_END)
|
||||||
|
{
|
||||||
|
deflateEnd(&zstream);
|
||||||
|
return (uint32_t)zstream.total_out;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
zerror = deflateEnd(&zstream);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint32 InflateData(const char* buffer, uint32 len, char* out_buffer, uint32 out_len_max) {
|
uint32 InflateData(const char* buffer, uint32 len, char* out_buffer, uint32 out_len_max) {
|
||||||
z_stream zstream;
|
z_stream zstream;
|
||||||
int zerror = 0;
|
int zerror = 0;
|
||||||
@ -241,7 +283,16 @@ Map *Map::LoadMapFile(std::string file) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Map::Load(std::string filename) {
|
#ifdef USE_MAP_MMFS
|
||||||
|
bool Map::Load(std::string filename, bool force_mmf_overwrite)
|
||||||
|
{
|
||||||
|
if (LoadMMF(filename, force_mmf_overwrite))
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
bool Map::Load(std::string filename)
|
||||||
|
{
|
||||||
|
#endif /*USE_MAP_MMFS*/
|
||||||
|
|
||||||
FILE *f = fopen(filename.c_str(), "rb");
|
FILE *f = fopen(filename.c_str(), "rb");
|
||||||
if(f) {
|
if(f) {
|
||||||
uint32 version;
|
uint32 version;
|
||||||
@ -253,10 +304,22 @@ bool Map::Load(std::string filename) {
|
|||||||
if(version == 0x01000000) {
|
if(version == 0x01000000) {
|
||||||
bool v = LoadV1(f);
|
bool v = LoadV1(f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
|
#ifdef USE_MAP_MMFS
|
||||||
|
if (v)
|
||||||
|
return SaveMMF(filename, force_mmf_overwrite);
|
||||||
|
#endif /*USE_MAP_MMFS*/
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
} else if(version == 0x02000000) {
|
} else if(version == 0x02000000) {
|
||||||
bool v = LoadV2(f);
|
bool v = LoadV2(f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
|
#ifdef USE_MAP_MMFS
|
||||||
|
if (v)
|
||||||
|
return SaveMMF(filename, force_mmf_overwrite);
|
||||||
|
#endif /*USE_MAP_MMFS*/
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
} else {
|
} else {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
@ -897,3 +960,199 @@ void Map::TranslateVertex(glm::vec3 &v, float tx, float ty, float tz) {
|
|||||||
v.y = v.y + ty;
|
v.y = v.y + ty;
|
||||||
v.z = v.z + tz;
|
v.z = v.z + tz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_MAP_MMFS
|
||||||
|
inline void strip_map_extension(std::string& map_file_name)
|
||||||
|
{
|
||||||
|
auto ext_off = map_file_name.find(".map");
|
||||||
|
if (ext_off != std::string::npos)
|
||||||
|
map_file_name.erase(ext_off, strlen(".map"));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool add_mmf_extension(std::string& mmf_file_name)
|
||||||
|
{
|
||||||
|
if (mmf_file_name.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
mmf_file_name.append(".mmf");
|
||||||
|
size_t dot_check = std::count(mmf_file_name.begin(), mmf_file_name.end(), '.');
|
||||||
|
|
||||||
|
return (dot_check == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Map::LoadMMF(const std::string& map_file_name, bool force_mmf_overwrite)
|
||||||
|
{
|
||||||
|
if (force_mmf_overwrite)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::string mmf_file_name = map_file_name;
|
||||||
|
strip_map_extension(mmf_file_name);
|
||||||
|
if (!add_mmf_extension(mmf_file_name)) {
|
||||||
|
Log.Out(Logs::General, Logs::Zone_Server, "Failed to load Map MMF file: '%s'", mmf_file_name.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *f = fopen(mmf_file_name.c_str(), "rb");
|
||||||
|
if (!f) {
|
||||||
|
Log.Out(Logs::General, Logs::Zone_Server, "Failed to load Map MMF file: '%s' - could not open file", mmf_file_name.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 file_version;
|
||||||
|
if (fread(&file_version, sizeof(uint32), 1, f) != 1) {
|
||||||
|
fclose(f);
|
||||||
|
Log.Out(Logs::General, Logs::Zone_Server, "Failed to load Map MMF file: '%s' - f@file_version", mmf_file_name.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 rm_buffer_size;
|
||||||
|
if (fread(&rm_buffer_size, sizeof(uint32), 1, f) != 1) {
|
||||||
|
fclose(f);
|
||||||
|
Log.Out(Logs::General, Logs::Zone_Server, "Failed to load Map MMF file: '%s' - f@rm_buffer_size", mmf_file_name.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 rm_buffer_crc32;
|
||||||
|
if (fread(&rm_buffer_crc32, sizeof(uint32), 1, f) != 1) {
|
||||||
|
fclose(f);
|
||||||
|
Log.Out(Logs::General, Logs::Zone_Server, "Failed to load Map MMF file: '%s' - f@rm_buffer_crc32", mmf_file_name.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (rm_buffer_crc32 != /*crc32_check*/ 0) {
|
||||||
|
fclose(f);
|
||||||
|
Log.Out(Logs::General, Logs::Zone_Server, "Failed to load Map MMF file: '%s' - bad rm_buffer checksum", mmf_file_name.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 mmf_buffer_size;
|
||||||
|
if (fread(&mmf_buffer_size, sizeof(uint32), 1, f) != 1) {
|
||||||
|
fclose(f);
|
||||||
|
Log.Out(Logs::General, Logs::Zone_Server, "Failed to load Map MMF file: '%s' - f@mmf_buffer_size", mmf_file_name.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<char> mmf_buffer(mmf_buffer_size);
|
||||||
|
if (fread(mmf_buffer.data(), mmf_buffer_size, 1, f) != 1) {
|
||||||
|
fclose(f);
|
||||||
|
Log.Out(Logs::General, Logs::Zone_Server, "Failed to load Map MMF file: '%s' - f@mmf_buffer", mmf_file_name.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
std::vector<char> rm_buffer(rm_buffer_size);
|
||||||
|
uint32 v = InflateData(mmf_buffer.data(), mmf_buffer_size, rm_buffer.data(), rm_buffer_size);
|
||||||
|
|
||||||
|
if (imp) {
|
||||||
|
imp->rm->release();
|
||||||
|
imp->rm = nullptr;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
imp = new impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool load_success = false;
|
||||||
|
imp->rm = loadRaycastMesh(rm_buffer, load_success);
|
||||||
|
if (imp->rm && !load_success) {
|
||||||
|
imp->rm->release();
|
||||||
|
imp->rm = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!imp->rm) {
|
||||||
|
delete imp;
|
||||||
|
imp = nullptr;
|
||||||
|
Log.Out(Logs::General, Logs::Zone_Server, "Failed to load Map MMF file: '%s' - null RaycastMesh", mmf_file_name.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Map::SaveMMF(const std::string& map_file_name, bool force_mmf_overwrite)
|
||||||
|
{
|
||||||
|
if (!imp || !imp->rm) {
|
||||||
|
Log.Out(Logs::General, Logs::Zone_Server, "Failed to save Map MMF file - No implementation (map_file_name: '%s')", map_file_name.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string mmf_file_name = map_file_name;
|
||||||
|
strip_map_extension(mmf_file_name);
|
||||||
|
if (!add_mmf_extension(mmf_file_name)) {
|
||||||
|
Log.Out(Logs::General, Logs::Zone_Server, "Failed to save Map MMF file: '%s'", mmf_file_name.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE* f = fopen(mmf_file_name.c_str(), "rb");
|
||||||
|
if (f) {
|
||||||
|
fclose(f);
|
||||||
|
if (!force_mmf_overwrite)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<char> rm_buffer; // size set in MyRaycastMesh::serialize()
|
||||||
|
serializeRaycastMesh(imp->rm, rm_buffer);
|
||||||
|
if (rm_buffer.empty()) {
|
||||||
|
Log.Out(Logs::General, Logs::Zone_Server, "Failed to save Map MMF file: '%s' - empty RaycastMesh buffer", mmf_file_name.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 rm_buffer_size = rm_buffer.size();
|
||||||
|
uint32 mmf_buffer_size = EstimateDeflateBuffer(rm_buffer.size());
|
||||||
|
|
||||||
|
std::vector<char> mmf_buffer(mmf_buffer_size);
|
||||||
|
|
||||||
|
mmf_buffer_size = DeflateData(rm_buffer.data(), rm_buffer.size(), mmf_buffer.data(), mmf_buffer.size());
|
||||||
|
if (!mmf_buffer_size) {
|
||||||
|
Log.Out(Logs::General, Logs::Zone_Server, "Failed to save Map MMF file: '%s' - null MMF buffer size", mmf_file_name.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
f = fopen(mmf_file_name.c_str(), "wb");
|
||||||
|
if (!f) {
|
||||||
|
Log.Out(Logs::General, Logs::Zone_Server, "Failed to save Map MMF file: '%s' - could not open file", mmf_file_name.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 file_version = 0;
|
||||||
|
if (fwrite(&file_version, sizeof(uint32), 1, f) != 1) {
|
||||||
|
fclose(f);
|
||||||
|
std::remove(mmf_file_name.c_str());
|
||||||
|
Log.Out(Logs::General, Logs::Zone_Server, "Failed to save Map MMF file: '%s' - f@file_version", mmf_file_name.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fwrite(&rm_buffer_size, sizeof(uint32), 1, f) != 1) {
|
||||||
|
fclose(f);
|
||||||
|
std::remove(mmf_file_name.c_str());
|
||||||
|
Log.Out(Logs::General, Logs::Zone_Server, "Failed to save Map MMF file: '%s' - f@rm_buffer_size", mmf_file_name.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 rm_buffer_crc32 = 0;
|
||||||
|
if (fwrite(&rm_buffer_crc32, sizeof(uint32), 1, f) != 1) {
|
||||||
|
fclose(f);
|
||||||
|
std::remove(mmf_file_name.c_str());
|
||||||
|
Log.Out(Logs::General, Logs::Zone_Server, "Failed to save Map MMF file: '%s' - f@rm_buffer_crc32", mmf_file_name.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fwrite(&mmf_buffer_size, sizeof(uint32), 1, f) != 1) {
|
||||||
|
fclose(f);
|
||||||
|
std::remove(mmf_file_name.c_str());
|
||||||
|
Log.Out(Logs::General, Logs::Zone_Server, "Failed to save Map MMF file: '%s' - f@mmf_buffer_size", mmf_file_name.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fwrite(mmf_buffer.data(), mmf_buffer_size, 1, f) != 1) {
|
||||||
|
fclose(f);
|
||||||
|
std::remove(mmf_file_name.c_str());
|
||||||
|
Log.Out(Logs::General, Logs::Zone_Server, "Failed to save Map MMF file: '%s' - f@mmf_buffer", mmf_file_name.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /*USE_MAP_MMFS*/
|
||||||
|
|||||||
11
zone/map.h
11
zone/map.h
@ -42,7 +42,13 @@ public:
|
|||||||
bool LineIntersectsZone(glm::vec3 start, glm::vec3 end, float step, glm::vec3 *result) const;
|
bool LineIntersectsZone(glm::vec3 start, glm::vec3 end, float step, glm::vec3 *result) const;
|
||||||
bool LineIntersectsZoneNoZLeaps(glm::vec3 start, glm::vec3 end, float step_mag, glm::vec3 *result) const;
|
bool LineIntersectsZoneNoZLeaps(glm::vec3 start, glm::vec3 end, float step_mag, glm::vec3 *result) const;
|
||||||
bool CheckLoS(glm::vec3 myloc, glm::vec3 oloc) const;
|
bool CheckLoS(glm::vec3 myloc, glm::vec3 oloc) const;
|
||||||
|
|
||||||
|
#ifdef USE_MAP_MMFS
|
||||||
|
bool Load(std::string filename, bool force_mmf_overwrite = false);
|
||||||
|
#else
|
||||||
bool Load(std::string filename);
|
bool Load(std::string filename);
|
||||||
|
#endif
|
||||||
|
|
||||||
static Map *LoadMapFile(std::string file);
|
static Map *LoadMapFile(std::string file);
|
||||||
private:
|
private:
|
||||||
void RotateVertex(glm::vec3 &v, float rx, float ry, float rz);
|
void RotateVertex(glm::vec3 &v, float rx, float ry, float rz);
|
||||||
@ -51,6 +57,11 @@ private:
|
|||||||
bool LoadV1(FILE *f);
|
bool LoadV1(FILE *f);
|
||||||
bool LoadV2(FILE *f);
|
bool LoadV2(FILE *f);
|
||||||
|
|
||||||
|
#ifdef USE_MAP_MMFS
|
||||||
|
bool LoadMMF(const std::string& map_file_name, bool force_mmf_overwrite);
|
||||||
|
bool SaveMMF(const std::string& map_file_name, bool force_mmf_overwrite);
|
||||||
|
#endif /*USE_MAP_MMFS*/
|
||||||
|
|
||||||
struct impl;
|
struct impl;
|
||||||
impl *imp;
|
impl *imp;
|
||||||
};
|
};
|
||||||
|
|||||||
21
zone/net.cpp
21
zone/net.cpp
@ -116,6 +116,27 @@ int main(int argc, char** argv) {
|
|||||||
Log.LoadLogSettingsDefaults();
|
Log.LoadLogSettingsDefaults();
|
||||||
|
|
||||||
set_exception_handler();
|
set_exception_handler();
|
||||||
|
|
||||||
|
#ifdef USE_MAP_MMFS
|
||||||
|
if (argc == 3 && strcasecmp(argv[1], "convert_map") == 0) {
|
||||||
|
if (!ZoneConfig::LoadConfig())
|
||||||
|
return 1;
|
||||||
|
Config = ZoneConfig::get();
|
||||||
|
|
||||||
|
std::string mapfile = argv[2];
|
||||||
|
std::transform(mapfile.begin(), mapfile.end(), mapfile.begin(), ::tolower);
|
||||||
|
std::string filename = Config->MapDir;
|
||||||
|
filename += mapfile;
|
||||||
|
|
||||||
|
auto m = new Map();
|
||||||
|
auto success = m->Load(filename, true);
|
||||||
|
delete m;
|
||||||
|
std::cout << mapfile.c_str() << " conversion " << (success ? "succeeded" : "failed") << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /*USE_MAP_MMFS*/
|
||||||
|
|
||||||
QServ = new QueryServ;
|
QServ = new QueryServ;
|
||||||
|
|
||||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading server configuration..");
|
Log.Out(Logs::General, Logs::Zone_Server, "Loading server configuration..");
|
||||||
|
|||||||
@ -914,6 +914,11 @@ public:
|
|||||||
RmUint32 mMaxNodeCount;
|
RmUint32 mMaxNodeCount;
|
||||||
NodeAABB *mNodes;
|
NodeAABB *mNodes;
|
||||||
TriVector mLeafTriangles;
|
TriVector mLeafTriangles;
|
||||||
|
|
||||||
|
#ifdef USE_MAP_MMFS
|
||||||
|
MyRaycastMesh(std::vector<char>& rm_buffer);
|
||||||
|
void serialize(std::vector<char>& rm_buffer);
|
||||||
|
#endif /*USE_MAP_MMFS*/
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -936,4 +941,253 @@ RaycastMesh * createRaycastMesh(RmUint32 vcount, // The number of vertices in t
|
|||||||
return static_cast< RaycastMesh * >(m);
|
return static_cast< RaycastMesh * >(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_MAP_MMFS
|
||||||
|
RaycastMesh* loadRaycastMesh(std::vector<char>& rm_buffer, bool& load_success)
|
||||||
|
{
|
||||||
|
if (rm_buffer.empty())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
auto m = new MyRaycastMesh(rm_buffer);
|
||||||
|
load_success = (m->mNodes != nullptr);
|
||||||
|
|
||||||
|
return static_cast<RaycastMesh*>(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
void serializeRaycastMesh(RaycastMesh* rm, std::vector<char>& rm_buffer)
|
||||||
|
{
|
||||||
|
if (!rm) {
|
||||||
|
rm_buffer.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static_cast<MyRaycastMesh*>(rm)->serialize(rm_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
MyRaycastMesh::MyRaycastMesh(std::vector<char>& rm_buffer)
|
||||||
|
{
|
||||||
|
mVcount = 0;
|
||||||
|
mVertices = nullptr;
|
||||||
|
mTcount = 0;
|
||||||
|
mIndices = nullptr;
|
||||||
|
mRaycastTriangles = nullptr;
|
||||||
|
mFaceNormals = nullptr;
|
||||||
|
mRaycastFrame = 0;
|
||||||
|
mMaxNodeCount = 0;
|
||||||
|
mNodeCount = 0;
|
||||||
|
mNodes = nullptr;
|
||||||
|
mRoot = nullptr;
|
||||||
|
|
||||||
|
size_t chunk_size = 0;
|
||||||
|
size_t bytes_read = 0;
|
||||||
|
size_t rm_buffer_size_ = rm_buffer.size();
|
||||||
|
if (!rm_buffer_size_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
char* buf = rm_buffer.data();
|
||||||
|
|
||||||
|
chunk_size = sizeof(RmUint32);
|
||||||
|
memcpy(&mVcount, buf, chunk_size);
|
||||||
|
buf += chunk_size;
|
||||||
|
bytes_read += chunk_size;
|
||||||
|
|
||||||
|
chunk_size = (sizeof(RmReal) * (3 * mVcount));
|
||||||
|
mVertices = (RmReal *)::malloc(chunk_size);
|
||||||
|
memcpy(mVertices, buf, chunk_size);
|
||||||
|
buf += chunk_size;
|
||||||
|
bytes_read += chunk_size;
|
||||||
|
|
||||||
|
chunk_size = sizeof(RmUint32);
|
||||||
|
memcpy(&mTcount, buf, chunk_size);
|
||||||
|
buf += chunk_size;
|
||||||
|
bytes_read += chunk_size;
|
||||||
|
|
||||||
|
chunk_size = (sizeof(RmUint32) * (3 * mTcount));
|
||||||
|
mIndices = (RmUint32 *)::malloc(chunk_size);
|
||||||
|
memcpy(mIndices, buf, chunk_size);
|
||||||
|
buf += chunk_size;
|
||||||
|
bytes_read += chunk_size;
|
||||||
|
|
||||||
|
chunk_size = (sizeof(RmUint32) * mTcount);
|
||||||
|
mRaycastTriangles = (RmUint32 *)::malloc(chunk_size);
|
||||||
|
memcpy(mRaycastTriangles, buf, chunk_size);
|
||||||
|
buf += chunk_size;
|
||||||
|
bytes_read += chunk_size;
|
||||||
|
|
||||||
|
chunk_size = (sizeof(RmReal) * (3 * mTcount));
|
||||||
|
mFaceNormals = (RmReal *)::malloc(chunk_size);
|
||||||
|
memcpy(mFaceNormals, buf, chunk_size);
|
||||||
|
buf += chunk_size;
|
||||||
|
bytes_read += chunk_size;
|
||||||
|
|
||||||
|
chunk_size = sizeof(RmUint32);
|
||||||
|
memcpy(&mRaycastFrame, buf, chunk_size);
|
||||||
|
buf += chunk_size;
|
||||||
|
bytes_read += chunk_size;
|
||||||
|
|
||||||
|
RmUint32 lt_size;
|
||||||
|
chunk_size = sizeof(RmUint32);
|
||||||
|
memcpy(<_size, buf, chunk_size);
|
||||||
|
buf += chunk_size;
|
||||||
|
bytes_read += chunk_size;
|
||||||
|
|
||||||
|
if (lt_size) {
|
||||||
|
mLeafTriangles.resize(lt_size);
|
||||||
|
chunk_size = (sizeof(RmUint32) * lt_size);
|
||||||
|
memcpy(&mLeafTriangles[0], buf, chunk_size);
|
||||||
|
buf += chunk_size;
|
||||||
|
bytes_read += chunk_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
chunk_size = sizeof(RmUint32);
|
||||||
|
memcpy(&mNodeCount, buf, chunk_size);
|
||||||
|
buf += chunk_size;
|
||||||
|
bytes_read += chunk_size;
|
||||||
|
|
||||||
|
mMaxNodeCount = mNodeCount;
|
||||||
|
|
||||||
|
mNodes = new NodeAABB[mMaxNodeCount];
|
||||||
|
mRoot = &mNodes[0];
|
||||||
|
|
||||||
|
for (int index = 0; index < mNodeCount; ++index) {
|
||||||
|
chunk_size = (sizeof(RmReal) * 3);
|
||||||
|
memcpy(&mNodes[index].mBounds.mMin, buf, chunk_size);
|
||||||
|
buf += chunk_size;
|
||||||
|
bytes_read += chunk_size;
|
||||||
|
|
||||||
|
chunk_size = (sizeof(RmReal) * 3);
|
||||||
|
memcpy(&mNodes[index].mBounds.mMax, buf, chunk_size);
|
||||||
|
buf += chunk_size;
|
||||||
|
bytes_read += chunk_size;
|
||||||
|
|
||||||
|
chunk_size = sizeof(RmUint32);
|
||||||
|
memcpy(&mNodes[index].mLeafTriangleIndex, buf, chunk_size);
|
||||||
|
buf += chunk_size;
|
||||||
|
bytes_read += chunk_size;
|
||||||
|
|
||||||
|
RmUint32 lNodeIndex;
|
||||||
|
chunk_size = sizeof(RmUint32);
|
||||||
|
memcpy(&lNodeIndex, buf, chunk_size);
|
||||||
|
if (lNodeIndex != TRI_EOF)
|
||||||
|
mNodes[index].mLeft = &mNodes[lNodeIndex];
|
||||||
|
buf += chunk_size;
|
||||||
|
bytes_read += chunk_size;
|
||||||
|
|
||||||
|
RmUint32 rNodeIndex;
|
||||||
|
chunk_size = sizeof(RmUint32);
|
||||||
|
memcpy(&rNodeIndex, buf, chunk_size);
|
||||||
|
if (rNodeIndex != TRI_EOF)
|
||||||
|
mNodes[index].mRight = &mNodes[rNodeIndex];
|
||||||
|
buf += chunk_size;
|
||||||
|
bytes_read += chunk_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bytes_read != rm_buffer_size_) {
|
||||||
|
delete[] mNodes;
|
||||||
|
::free(mVertices);
|
||||||
|
::free(mIndices);
|
||||||
|
::free(mFaceNormals);
|
||||||
|
::free(mRaycastTriangles);
|
||||||
|
|
||||||
|
mVcount = 0;
|
||||||
|
mVertices = nullptr;
|
||||||
|
mTcount = 0;
|
||||||
|
mIndices = nullptr;
|
||||||
|
mRaycastTriangles = nullptr;
|
||||||
|
mFaceNormals = nullptr;
|
||||||
|
mRaycastFrame = 0;
|
||||||
|
mLeafTriangles.clear();
|
||||||
|
mMaxNodeCount = 0;
|
||||||
|
mNodeCount = 0;
|
||||||
|
mNodes = nullptr;
|
||||||
|
mRoot = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyRaycastMesh::serialize(std::vector<char>& rm_buffer)
|
||||||
|
{
|
||||||
|
rm_buffer.clear();
|
||||||
|
|
||||||
|
size_t rm_buffer_size_ = 0;
|
||||||
|
|
||||||
|
rm_buffer_size_ += sizeof(RmUint32); // mVcount
|
||||||
|
rm_buffer_size_ += (sizeof(RmReal) * (3 * mVcount)); // mVertices
|
||||||
|
rm_buffer_size_ += sizeof(RmUint32); // mTcount
|
||||||
|
rm_buffer_size_ += (sizeof(RmUint32) * (3 * mTcount)); // mIndices
|
||||||
|
rm_buffer_size_ += (sizeof(RmUint32) * mTcount); // mRaycastTriangles
|
||||||
|
rm_buffer_size_ += (sizeof(RmReal) * (3 * mTcount)); // mFaceNormals
|
||||||
|
rm_buffer_size_ += sizeof(RmUint32); // mRaycastFrame
|
||||||
|
rm_buffer_size_ += sizeof(RmUint32); // mLeafTriangles.size()
|
||||||
|
rm_buffer_size_ += (sizeof(RmUint32) * (RmUint32)mLeafTriangles.size()); // mLeafTriangles
|
||||||
|
rm_buffer_size_ += sizeof(RmUint32); // mNodeCount
|
||||||
|
rm_buffer_size_ += (sizeof(RmReal) * (3 * mNodeCount)); // mNodes.mBounds.mMin
|
||||||
|
rm_buffer_size_ += (sizeof(RmReal) * (3 * mNodeCount)); // mNodes.mBounds.mMax
|
||||||
|
rm_buffer_size_ += (sizeof(RmUint32) * mNodeCount); // mNodes.mLeafTriangleIndex
|
||||||
|
rm_buffer_size_ += (sizeof(RmUint32) * mNodeCount); // mNodes.mLeft[Index]
|
||||||
|
rm_buffer_size_ += (sizeof(RmUint32) * mNodeCount); // mNodes.mRight[Index]
|
||||||
|
|
||||||
|
rm_buffer.resize(rm_buffer_size_);
|
||||||
|
|
||||||
|
char* buf = rm_buffer.data();
|
||||||
|
|
||||||
|
memcpy(buf, &mVcount, sizeof(RmUint32));
|
||||||
|
buf += sizeof(RmUint32);
|
||||||
|
|
||||||
|
memcpy(buf, mVertices, (sizeof(RmReal) * (3 * mVcount)));
|
||||||
|
buf += (sizeof(RmReal) * (3 * mVcount));
|
||||||
|
|
||||||
|
memcpy(buf, &mTcount, sizeof(RmUint32));
|
||||||
|
buf += sizeof(RmUint32);
|
||||||
|
|
||||||
|
memcpy(buf, mIndices, (sizeof(RmUint32) * (3 * mTcount)));
|
||||||
|
buf += (sizeof(RmUint32) * (3 * mTcount));
|
||||||
|
|
||||||
|
memcpy(buf, mRaycastTriangles, (sizeof(RmUint32) * mTcount));
|
||||||
|
buf += (sizeof(RmUint32) * mTcount);
|
||||||
|
|
||||||
|
if (!mFaceNormals) {
|
||||||
|
RmReal save_face[3];
|
||||||
|
getFaceNormal(0, &save_face[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(buf, mFaceNormals, (sizeof(RmReal) * (3 * mTcount)));
|
||||||
|
buf += (sizeof(RmReal) * (3 * mTcount));
|
||||||
|
|
||||||
|
memcpy(buf, &mRaycastFrame, sizeof(RmUint32));
|
||||||
|
buf += sizeof(RmUint32);
|
||||||
|
|
||||||
|
RmUint32 lt_size = (RmUint32)mLeafTriangles.size();
|
||||||
|
memcpy(buf, <_size, sizeof(RmUint32));
|
||||||
|
buf += sizeof(RmUint32);
|
||||||
|
|
||||||
|
if (lt_size) {
|
||||||
|
memcpy(buf, &mLeafTriangles[0], (sizeof(RmUint32) * lt_size));
|
||||||
|
buf += (sizeof(RmUint32) * lt_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(buf, &mNodeCount, sizeof(RmUint32));
|
||||||
|
buf += sizeof(RmUint32);
|
||||||
|
|
||||||
|
for (RmUint32 index = 0; index < mNodeCount; ++index) {
|
||||||
|
memcpy(buf, &mNodes[index].mBounds.mMin, (sizeof(RmReal) * 3));
|
||||||
|
buf += (sizeof(RmReal) * 3);
|
||||||
|
|
||||||
|
memcpy(buf, &mNodes[index].mBounds.mMax, (sizeof(RmReal) * 3));
|
||||||
|
buf += (sizeof(RmReal) * 3);
|
||||||
|
|
||||||
|
memcpy(buf, &mNodes[index].mLeafTriangleIndex, sizeof(RmUint32));
|
||||||
|
buf += sizeof(RmUint32);
|
||||||
|
|
||||||
|
RmUint32 lNodeIndex = TRI_EOF;
|
||||||
|
if (mNodes[index].mLeft)
|
||||||
|
lNodeIndex = ((RmUint32)mNodes[index].mLeft - (RmUint32)mNodes) / sizeof(NodeAABB);
|
||||||
|
memcpy(buf, &lNodeIndex, sizeof(RmUint32));
|
||||||
|
buf += sizeof(RmUint32);
|
||||||
|
|
||||||
|
RmUint32 rNodeIndex = TRI_EOF;
|
||||||
|
if (mNodes[index].mRight)
|
||||||
|
rNodeIndex = ((RmUint32)mNodes[index].mRight - (RmUint32)mNodes) / sizeof(NodeAABB);
|
||||||
|
memcpy(buf, &rNodeIndex, sizeof(RmUint32));
|
||||||
|
buf += sizeof(RmUint32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /*USE_MAP_MMFS*/
|
||||||
|
|||||||
@ -56,5 +56,11 @@ RaycastMesh * createRaycastMesh(RmUint32 vcount, // The number of vertices in t
|
|||||||
RmReal minAxisSize=0.01f // once a particular axis is less than this size, stop sub-dividing.
|
RmReal minAxisSize=0.01f // once a particular axis is less than this size, stop sub-dividing.
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#ifdef USE_MAP_MMFS
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
RaycastMesh* loadRaycastMesh(std::vector<char>& rm_buffer, bool& load_success);
|
||||||
|
void serializeRaycastMesh(RaycastMesh* rm, std::vector<char>& rm_buffer);
|
||||||
|
#endif /*USE_MAP_MMFS*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Loading…
x
Reference in New Issue
Block a user