mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 21:01: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_SANITIZE_LUA_LIBS
|
||||
#EQEMU_BUILD_CLIENT_FILES
|
||||
#EQEMU_USE_MAP_MMFS
|
||||
#EQEMU_MAP_DIR
|
||||
|
||||
#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)
|
||||
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.")
|
||||
|
||||
ADD_DEFINITIONS(-DEQDEBUG=${EQEMU_DEBUG_LEVEL})
|
||||
|
||||
@ -1,6 +1,18 @@
|
||||
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
|
||||
- THERE MAYBE BUGS
|
||||
- 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 <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) {
|
||||
z_stream zstream;
|
||||
int zerror = 0;
|
||||
@ -241,7 +283,16 @@ Map *Map::LoadMapFile(std::string file) {
|
||||
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");
|
||||
if(f) {
|
||||
uint32 version;
|
||||
@ -253,10 +304,22 @@ bool Map::Load(std::string filename) {
|
||||
if(version == 0x01000000) {
|
||||
bool v = LoadV1(f);
|
||||
fclose(f);
|
||||
|
||||
#ifdef USE_MAP_MMFS
|
||||
if (v)
|
||||
return SaveMMF(filename, force_mmf_overwrite);
|
||||
#endif /*USE_MAP_MMFS*/
|
||||
|
||||
return v;
|
||||
} else if(version == 0x02000000) {
|
||||
bool v = LoadV2(f);
|
||||
fclose(f);
|
||||
|
||||
#ifdef USE_MAP_MMFS
|
||||
if (v)
|
||||
return SaveMMF(filename, force_mmf_overwrite);
|
||||
#endif /*USE_MAP_MMFS*/
|
||||
|
||||
return v;
|
||||
} else {
|
||||
fclose(f);
|
||||
@ -897,3 +960,199 @@ void Map::TranslateVertex(glm::vec3 &v, float tx, float ty, float tz) {
|
||||
v.y = v.y + ty;
|
||||
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 LineIntersectsZoneNoZLeaps(glm::vec3 start, glm::vec3 end, float step_mag, glm::vec3 *result) 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);
|
||||
#endif
|
||||
|
||||
static Map *LoadMapFile(std::string file);
|
||||
private:
|
||||
void RotateVertex(glm::vec3 &v, float rx, float ry, float rz);
|
||||
@ -51,6 +57,11 @@ private:
|
||||
bool LoadV1(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;
|
||||
impl *imp;
|
||||
};
|
||||
|
||||
21
zone/net.cpp
21
zone/net.cpp
@ -116,6 +116,27 @@ int main(int argc, char** argv) {
|
||||
Log.LoadLogSettingsDefaults();
|
||||
|
||||
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;
|
||||
|
||||
Log.Out(Logs::General, Logs::Zone_Server, "Loading server configuration..");
|
||||
|
||||
@ -914,6 +914,11 @@ public:
|
||||
RmUint32 mMaxNodeCount;
|
||||
NodeAABB *mNodes;
|
||||
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);
|
||||
}
|
||||
|
||||
#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.
|
||||
);
|
||||
|
||||
#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
|
||||
Loading…
x
Reference in New Issue
Block a user