bool Map::LoadV2(FILE *f) { uint32 data_size; if (fread(&data_size, sizeof(data_size), 1, f) != 1) { return false; } uint32 buffer_size; if (fread(&buffer_size, sizeof(buffer_size), 1, f) != 1) { return false; } std::vector<char> data; data.resize(data_size); if (fread(&data[0], data_size, 1, f) != 1) { return false; } std::vector<char> buffer; buffer.resize(buffer_size); uint32 v = InflateData(&data[0], data_size, &buffer[0], buffer_size); char *buf = &buffer[0]; uint32 vert_count; uint32 ind_count; uint32 nc_vert_count; uint32 nc_ind_count; uint32 model_count; uint32 plac_count; uint32 plac_group_count; uint32 tile_count; uint32 quads_per_tile; float units_per_vertex; vert_count = *(uint32*)buf; buf += sizeof(uint32); ind_count = *(uint32*)buf; buf += sizeof(uint32); nc_vert_count = *(uint32*)buf; buf += sizeof(uint32); nc_ind_count = *(uint32*)buf; buf += sizeof(uint32); model_count = *(uint32*)buf; buf += sizeof(uint32); plac_count = *(uint32*)buf; buf += sizeof(uint32); plac_group_count = *(uint32*)buf; buf += sizeof(uint32); tile_count = *(uint32*)buf; buf += sizeof(uint32); quads_per_tile = *(uint32*)buf; buf += sizeof(uint32); units_per_vertex = *(float*)buf; buf += sizeof(float); std::vector<glm::vec3> verts; verts.reserve(vert_count); std::vector<uint32> indices; indices.reserve(ind_count); for (uint32 i = 0; i < vert_count; ++i) { float x; float y; float z; x = *(float*)buf; buf += sizeof(float); y = *(float*)buf; buf += sizeof(float); z = *(float*)buf; buf += sizeof(float); verts.emplace_back(x, y, z); } for (uint32 i = 0; i < ind_count; ++i) { indices.emplace_back(*(uint32 *)buf); buf += sizeof(uint32); } for (uint32 i = 0; i < nc_vert_count; ++i) { buf += sizeof(float) * 3; } for (uint32 i = 0; i < nc_ind_count; ++i) { buf += sizeof(uint32); } std::map<std::string, std::unique_ptr<ModelEntry>> models; for (uint32 i = 0; i < model_count; ++i) { std::unique_ptr<ModelEntry> me(new ModelEntry); std::string name = buf; buf += name.length() + 1; uint32 vert_count = *(uint32*)buf; buf += sizeof(uint32); uint32 poly_count = *(uint32*)buf; buf += sizeof(uint32); me->verts.reserve(vert_count); for (uint32 j = 0; j < vert_count; ++j) { float x = *(float*)buf; buf += sizeof(float); float y = *(float*)buf; buf += sizeof(float); float z = *(float*)buf; buf += sizeof(float); me->verts.emplace_back(x, y, z); } me->polys.reserve(poly_count); for (uint32 j = 0; j < poly_count; ++j) { uint32 v1 = *(uint32*)buf; buf += sizeof(uint32); uint32 v2 = *(uint32*)buf; buf += sizeof(uint32); uint32 v3 = *(uint32*)buf; buf += sizeof(uint32); uint8 vis = *(uint8*)buf; buf += sizeof(uint8); ModelEntry::Poly p; p.v1 = v1; p.v2 = v2; p.v3 = v3; p.vis = vis; me->polys.push_back(p); } models[name] = std::move(me); } for (uint32 i = 0; i < plac_count; ++i) { std::string name = buf; buf += name.length() + 1; float x = *(float*)buf; buf += sizeof(float); float y = *(float*)buf; buf += sizeof(float); float z = *(float*)buf; buf += sizeof(float); float x_rot = *(float*)buf; buf += sizeof(float); float y_rot = *(float*)buf; buf += sizeof(float); float z_rot = *(float*)buf; buf += sizeof(float); float x_scale = *(float*)buf; buf += sizeof(float); float y_scale = *(float*)buf; buf += sizeof(float); float z_scale = *(float*)buf; buf += sizeof(float); if (models.count(name) == 0) continue; auto &model = models[name]; auto &mod_polys = model->polys; auto &mod_verts = model->verts; for (uint32 j = 0; j < mod_polys.size(); ++j) { auto ¤t_poly = mod_polys[j]; if (current_poly.vis == 0) continue; auto v1 = mod_verts[current_poly.v1]; auto v2 = mod_verts[current_poly.v2]; auto v3 = mod_verts[current_poly.v3]; RotateVertex(v1, x_rot, y_rot, z_rot); RotateVertex(v2, x_rot, y_rot, z_rot); RotateVertex(v3, x_rot, y_rot, z_rot); ScaleVertex(v1, x_scale, y_scale, z_scale); ScaleVertex(v2, x_scale, y_scale, z_scale); ScaleVertex(v3, x_scale, y_scale, z_scale); TranslateVertex(v1, x, y, z); TranslateVertex(v2, x, y, z); TranslateVertex(v3, x, y, z); verts.emplace_back(v1.y, v1.x, v1.z); // x/y swapped verts.emplace_back(v2.y, v2.x, v2.z); verts.emplace_back(v3.y, v3.x, v3.z); indices.emplace_back((uint32)verts.size() - 3); indices.emplace_back((uint32)verts.size() - 2); indices.emplace_back((uint32)verts.size() - 1); } } for (uint32 i = 0; i < plac_group_count; ++i) { float x = *(float*)buf; buf += sizeof(float); float y = *(float*)buf; buf += sizeof(float); float z = *(float*)buf; buf += sizeof(float); float x_rot = *(float*)buf; buf += sizeof(float); float y_rot = *(float*)buf; buf += sizeof(float); float z_rot = *(float*)buf; buf += sizeof(float); float x_scale = *(float*)buf; buf += sizeof(float); float y_scale = *(float*)buf; buf += sizeof(float); float z_scale = *(float*)buf; buf += sizeof(float); float x_tile = *(float*)buf; buf += sizeof(float); float y_tile = *(float*)buf; buf += sizeof(float); float z_tile = *(float*)buf; buf += sizeof(float); uint32 p_count = *(uint32*)buf; buf += sizeof(uint32); for (uint32 j = 0; j < p_count; ++j) { std::string name = buf; buf += name.length() + 1; float p_x = *(float*)buf; buf += sizeof(float); float p_y = *(float*)buf; buf += sizeof(float); float p_z = *(float*)buf; buf += sizeof(float); float p_x_rot = *(float*)buf * 3.14159f / 180; buf += sizeof(float); float p_y_rot = *(float*)buf * 3.14159f / 180; buf += sizeof(float); float p_z_rot = *(float*)buf * 3.14159f / 180; buf += sizeof(float); float p_x_scale = *(float*)buf; buf += sizeof(float); float p_y_scale = *(float*)buf; buf += sizeof(float); float p_z_scale = *(float*)buf; buf += sizeof(float); if (models.count(name) == 0) continue; auto &model = models[name]; for (size_t k = 0; k < model->polys.size(); ++k) { auto &poly = model->polys[k]; if (poly.vis == 0) continue; glm::vec3 v1, v2, v3; v1 = model->verts[poly.v1]; v2 = model->verts[poly.v2]; v3 = model->verts[poly.v3]; ScaleVertex(v1, p_x_scale, p_y_scale, p_z_scale); ScaleVertex(v2, p_x_scale, p_y_scale, p_z_scale); ScaleVertex(v3, p_x_scale, p_y_scale, p_z_scale); TranslateVertex(v1, p_x, p_y, p_z); TranslateVertex(v2, p_x, p_y, p_z); TranslateVertex(v3, p_x, p_y, p_z); RotateVertex(v1, x_rot * 3.14159f / 180.0f, 0, 0); RotateVertex(v2, x_rot * 3.14159f / 180.0f, 0, 0); RotateVertex(v3, x_rot * 3.14159f / 180.0f, 0, 0); RotateVertex(v1, 0, y_rot * 3.14159f / 180.0f, 0); RotateVertex(v2, 0, y_rot * 3.14159f / 180.0f, 0); RotateVertex(v3, 0, y_rot * 3.14159f / 180.0f, 0); glm::vec3 correction(p_x, p_y, p_z); RotateVertex(correction, x_rot * 3.14159f / 180.0f, 0, 0); TranslateVertex(v1, -correction.x, -correction.y, -correction.z); TranslateVertex(v2, -correction.x, -correction.y, -correction.z); TranslateVertex(v3, -correction.x, -correction.y, -correction.z); RotateVertex(v1, p_x_rot, 0, 0); RotateVertex(v2, p_x_rot, 0, 0); RotateVertex(v3, p_x_rot, 0, 0); RotateVertex(v1, 0, -p_y_rot, 0); RotateVertex(v2, 0, -p_y_rot, 0); RotateVertex(v3, 0, -p_y_rot, 0); RotateVertex(v1, 0, 0, p_z_rot); RotateVertex(v2, 0, 0, p_z_rot); RotateVertex(v3, 0, 0, p_z_rot); TranslateVertex(v1, correction.x, correction.y, correction.z); TranslateVertex(v2, correction.x, correction.y, correction.z); TranslateVertex(v3, correction.x, correction.y, correction.z); RotateVertex(v1, 0, 0, z_rot * 3.14159f / 180.0f); RotateVertex(v2, 0, 0, z_rot * 3.14159f / 180.0f); RotateVertex(v3, 0, 0, z_rot * 3.14159f / 180.0f); ScaleVertex(v1, x_scale, y_scale, z_scale); ScaleVertex(v2, x_scale, y_scale, z_scale); ScaleVertex(v3, x_scale, y_scale, z_scale); TranslateVertex(v1, x_tile, y_tile, z_tile); TranslateVertex(v2, x_tile, y_tile, z_tile); TranslateVertex(v3, x_tile, y_tile, z_tile); TranslateVertex(v1, x, y, z); TranslateVertex(v2, x, y, z); TranslateVertex(v3, x, y, z); verts.emplace_back(v1.y, v1.x, v1.z); // x/y swapped verts.emplace_back(v2.y, v2.x, v2.z); verts.emplace_back(v3.y, v3.x, v3.z); indices.emplace_back((uint32)verts.size() - 3); indices.emplace_back((uint32)verts.size() - 2); indices.emplace_back((uint32)verts.size() - 1); } } } uint32 ter_quad_count = (quads_per_tile * quads_per_tile); uint32 ter_vert_count = ((quads_per_tile + 1) * (quads_per_tile + 1)); std::vector<uint8> flags; std::vector<float> floats; flags.resize(ter_quad_count); floats.resize(ter_vert_count); for (uint32 i = 0; i < tile_count; ++i) { bool flat; flat = *(bool*)buf; buf += sizeof(bool); float x; x = *(float*)buf; buf += sizeof(float); float y; y = *(float*)buf; buf += sizeof(float); if (flat) { float z; z = *(float*)buf; buf += sizeof(float); float QuadVertex1X = x; float QuadVertex1Y = y; float QuadVertex1Z = z; float QuadVertex2X = QuadVertex1X + (quads_per_tile * units_per_vertex); float QuadVertex2Y = QuadVertex1Y; float QuadVertex2Z = QuadVertex1Z; float QuadVertex3X = QuadVertex2X; float QuadVertex3Y = QuadVertex1Y + (quads_per_tile * units_per_vertex); float QuadVertex3Z = QuadVertex1Z; float QuadVertex4X = QuadVertex1X; float QuadVertex4Y = QuadVertex3Y; float QuadVertex4Z = QuadVertex1Z; uint32 current_vert = (uint32)verts.size() + 3; verts.emplace_back(QuadVertex1X, QuadVertex1Y, QuadVertex1Z); verts.emplace_back(QuadVertex2X, QuadVertex2Y, QuadVertex2Z); verts.emplace_back(QuadVertex3X, QuadVertex3Y, QuadVertex3Z); verts.emplace_back(QuadVertex4X, QuadVertex4Y, QuadVertex4Z); indices.emplace_back(current_vert); indices.emplace_back(current_vert - 2); indices.emplace_back(current_vert - 1); indices.emplace_back(current_vert); indices.emplace_back(current_vert - 3); indices.emplace_back(current_vert - 2); } else { //read flags for (uint32 j = 0; j < ter_quad_count; ++j) { uint8 f; f = *(uint8*)buf; buf += sizeof(uint8); flags[j] = f; } //read floats for (uint32 j = 0; j < ter_vert_count; ++j) { float f; f = *(float*)buf; buf += sizeof(float); floats[j] = f; } int row_number = -1; std::map<std::tuple<float, float, float>, uint32> cur_verts; for (uint32 quad = 0; quad < ter_quad_count; ++quad) { if ((quad % quads_per_tile) == 0) { ++row_number; } if (flags[quad] & 0x01) continue; float QuadVertex1X = x + (row_number * units_per_vertex); float QuadVertex1Y = y + (quad % quads_per_tile) * units_per_vertex; float QuadVertex1Z = floats[quad + row_number]; float QuadVertex2X = QuadVertex1X + units_per_vertex; float QuadVertex2Y = QuadVertex1Y; float QuadVertex2Z = floats[quad + row_number + quads_per_tile + 1]; float QuadVertex3X = QuadVertex1X + units_per_vertex; float QuadVertex3Y = QuadVertex1Y + units_per_vertex; float QuadVertex3Z = floats[quad + row_number + quads_per_tile + 2]; float QuadVertex4X = QuadVertex1X; float QuadVertex4Y = QuadVertex1Y + units_per_vertex; float QuadVertex4Z = floats[quad + row_number + 1]; uint32 i1, i2, i3, i4; std::tuple<float, float, float> t = std::make_tuple(QuadVertex1X, QuadVertex1Y, QuadVertex1Z); auto iter = cur_verts.find(t); if (iter != cur_verts.end()) { i1 = iter->second; } else { i1 = (uint32)verts.size(); verts.emplace_back(QuadVertex1X, QuadVertex1Y, QuadVertex1Z); cur_verts[std::make_tuple(QuadVertex1X, QuadVertex1Y, QuadVertex1Z)] = i1; } t = std::make_tuple(QuadVertex2X, QuadVertex2Y, QuadVertex2Z); iter = cur_verts.find(t); if (iter != cur_verts.end()) { i2 = iter->second; } else { i2 = (uint32)verts.size(); verts.emplace_back(QuadVertex2X, QuadVertex2Y, QuadVertex2Z); cur_verts[std::make_tuple(QuadVertex2X, QuadVertex2Y, QuadVertex2Z)] = i2; } t = std::make_tuple(QuadVertex3X, QuadVertex3Y, QuadVertex3Z); iter = cur_verts.find(t); if (iter != cur_verts.end()) { i3 = iter->second; } else { i3 = (uint32)verts.size(); verts.emplace_back(QuadVertex3X, QuadVertex3Y, QuadVertex3Z); cur_verts[std::make_tuple(QuadVertex3X, QuadVertex3Y, QuadVertex3Z)] = i3; } t = std::make_tuple(QuadVertex4X, QuadVertex4Y, QuadVertex4Z); iter = cur_verts.find(t); if (iter != cur_verts.end()) { i4 = iter->second; } else { i4 = (uint32)verts.size(); verts.emplace_back(QuadVertex4X, QuadVertex4Y, QuadVertex4Z); cur_verts[std::make_tuple(QuadVertex4X, QuadVertex4Y, QuadVertex4Z)] = i4; } indices.emplace_back(i4); indices.emplace_back(i2); indices.emplace_back(i3); indices.emplace_back(i4); indices.emplace_back(i1); indices.emplace_back(i2); } } } uint32 face_count = indices.size() / 3; if (imp) { imp->rm->release(); imp->rm = nullptr; } else { imp = new impl; } imp->rm = createRaycastMesh((RmUint32)verts.size(), (const RmReal*)&verts[0], face_count, &indices[0]); if (!imp->rm) { delete imp; imp = nullptr; return false; } return true; }
bool MapGeometryLoader::load() { uint32_t counter = 0; if (!Build()) { return false; } // load terrain geometry if (terrain) { const auto& tiles = terrain->GetTiles(); uint32_t quads_per_tile = terrain->GetQuadsPerTile(); float units_per_vertex = terrain->GetUnitsPerVertex(); uint32_t vert_count = ((quads_per_tile + 1) * (quads_per_tile + 1)); uint32_t quad_count = (quads_per_tile * quads_per_tile); for (uint32_t i = 0; i < tiles.size(); ++i) { auto& tile = tiles[i]; bool flat = tile->IsFlat(); float x = tile->GetX(); float y = tile->GetY(); if (flat) { float z = tile->GetFloats()[0]; // get x,y of corner point for this quad float dt = quads_per_tile * units_per_vertex; addVertex(x, z, y); addVertex(x + dt, z, y); addVertex(x + dt, z, y + dt); addVertex(x, z, y + dt); addTriangle(counter + 0, counter + 2, counter + 1); addTriangle(counter + 2, counter + 0, counter + 3); counter += 4; } else { auto& floats = tile->GetFloats(); int row_number = -1; for (uint32_t quad = 0; quad < quad_count; ++quad) { if (quad % quads_per_tile == 0) ++row_number; if (tile->GetFlags()[quad] & 0x01) continue; // get x,y of corner point for this quad float _x = x + (row_number * units_per_vertex); float _y = y + (quad % quads_per_tile) * units_per_vertex; float dt = units_per_vertex; float z1 = floats[quad + row_number]; float z2 = floats[quad + row_number + quads_per_tile + 1]; float z3 = floats[quad + row_number + quads_per_tile + 2]; float z4 = floats[quad + row_number + 1]; addVertex(_x, z1, _y); addVertex(_x + dt, z2, _y); addVertex(_x + dt, z3, _y + dt); addVertex(_x, z4, _y + dt); addTriangle(counter + 0, counter + 2, counter + 1); addTriangle(counter + 2, counter + 0, counter + 3); counter += 4; } } } } for (uint32_t index = 0; index < collide_indices.size(); index += 3, counter += 3) { uint32_t vert_index1 = collide_indices[index]; const glm::vec3& vert1 = collide_verts[vert_index1]; addVertex(vert1.x, vert1.z, vert1.y); uint32_t vert_index2 = collide_indices[index + 2]; const glm::vec3& vert2 = collide_verts[vert_index2]; addVertex(vert2.x, vert2.z, vert2.y); uint32_t vert_index3 = collide_indices[index + 1]; const glm::vec3& vert3 = collide_verts[vert_index3]; addVertex(vert3.x, vert3.z, vert3.y); addTriangle(counter, counter + 2, counter + 1); } // Load models for (auto iter : map_models) { std::string name = iter.first; std::shared_ptr<EQEmu::S3D::Geometry> model = iter.second; std::shared_ptr<ModelEntry> entry = std::make_shared<ModelEntry>(); for (const auto& vert : model->GetVertices()) { entry->verts.push_back(vert.pos); } for (const auto& poly : model->GetPolygons()) { entry->polys.emplace_back( ModelEntry::Poly{ poly.verts[0], poly.verts[1], poly.verts[2], (poly.flags & 0x10) == 0 }); } m_models.emplace(std::make_pair(std::move(name), std::move(entry))); } for (auto iter : map_eqg_models) { bool first = true; std::string name = iter.first; std::shared_ptr<EQEmu::EQG::Geometry> model = iter.second; std::shared_ptr<ModelEntry> entry = std::make_shared<ModelEntry>(); for (const auto& vert : model->GetVertices()) { entry->verts.push_back(vert.pos); } for (const auto& poly : model->GetPolygons()) { // 0x10 = invisible // 0x01 = no collision entry->polys.emplace_back( ModelEntry::Poly{ poly.verts[0], poly.verts[1], poly.verts[2], (poly.flags & 0x11) == 0 }); } m_models.emplace(std::make_pair(std::move(name), std::move(entry))); } auto AddTriangle = [&](const glm::vec3& v1, const glm::vec3& v2, const glm::vec3& v3) { addVertex(v1.y, v1.z, v1.x); addVertex(v2.y, v2.z, v2.x); addVertex(v3.y, v3.z, v3.x); addTriangle(counter, counter + 1, counter + 2); counter += 3; }; for (const auto& obj : map_placeables) { const std::string& name = obj->GetFileName(); auto modelIter = m_models.find(name); if (modelIter == m_models.end()) continue; // some objects have a really low z, just ignore them. if (obj->GetZ() < -30000) continue; const auto& model = modelIter->second; for (const auto& poly : model->polys) { if (!poly.vis) continue; glm::vec3 v[3]; for (int i = 0; i < 3; i++) { v[i] = model->verts[poly.v[i]]; RotateVertex(v[i], GetRotation(obj)); ScaleVertex(v[i], GetScale(obj)); TranslateVertex(v[i], GetTranslation(obj)); } AddTriangle(v[0], v[1], v[2]); } } for (const auto& group : map_group_placeables) { for (const auto& obj : group->GetPlaceables()) { const std::string& name = obj->GetFileName(); auto modelIter = m_models.find(name); if (modelIter == m_models.end()) continue; const auto& model = modelIter->second; for (const auto& poly : model->polys) { if (!poly.vis) continue; glm::vec3 v_[3]; for (int i = 0; i < 3; i++) { glm::vec3& v = v_[i]; v = model->verts[poly.v[i]]; ScaleVertex(v, GetScale(obj)); TranslateVertex(v, GetTranslation(obj)); RotateVertex(v, group->GetRotationX() * M_PI / 180, 0, 0); RotateVertex(v, 0, group->GetRotationY() * M_PI / 180, 0); glm::vec3 correction = GetTranslation(obj); RotateVertex(correction, group->GetRotationX() * M_PI / 180, 0, 0); TranslateVertex(v, -correction.x, -correction.y, -correction.z); RotateVertex(v, obj->GetRotateX() * M_PI / 180, 0, 0); RotateVertex(v, 0, -obj->GetRotateY() * M_PI / 180, 0); RotateVertex(v, 0, 0, obj->GetRotateZ() * M_PI / 180); TranslateVertex(v, correction.x, correction.y, correction.z); RotateVertex(v, 0, 0, group->GetRotationZ() * M_PI / 180); ScaleVertex(v, GetScale(group)); TranslateVertex(v, group->GetTileX(), group->GetTileY(), group->GetTileZ()); TranslateVertex(v, GetTranslation(group)); } AddTriangle(v_[0], v_[1], v_[2]); } } } //const auto& non_collide_indices = map.GetNonCollideIndices(); //for (uint32_t index = 0; index < non_collide_indices.size(); index += 3, counter += 3) //{ // uint32_t vert_index1 = non_collide_indices[index]; // const glm::vec3& vert1 = map.GetNonCollideVert(vert_index1); // addVertex(vert1.x, vert1.z, vert1.y, vcap); // uint32_t vert_index2 = non_collide_indices[index + 1]; // const glm::vec3& vert2 = map.GetNonCollideVert(vert_index2); // addVertex(vert2.x, vert2.z, vert2.y, vcap); // uint32_t vert_index3 = non_collide_indices[index + 2]; // const glm::vec3& vert3 = map.GetNonCollideVert(vert_index3); // addVertex(vert3.x, vert3.z, vert3.y, vcap); // addTriangle(counter, counter + 2, counter + 1, tcap); //} LoadDoors(); //message = "Calculating Surface Normals..."; m_normals = new float[m_triCount*3]; for (int i = 0; i < m_triCount*3; i += 3) { const float* v0 = &m_verts[m_tris[i]*3]; const float* v1 = &m_verts[m_tris[i+1]*3]; const float* v2 = &m_verts[m_tris[i+2]*3]; float e0[3], e1[3]; for (int j = 0; j < 3; ++j) { e0[j] = v1[j] - v0[j]; e1[j] = v2[j] - v0[j]; } float* n = &m_normals[i]; n[0] = e0[1]*e1[2] - e0[2]*e1[1]; n[1] = e0[2]*e1[0] - e0[0]*e1[2]; n[2] = e0[0]*e1[1] - e0[1]*e1[0]; float d = sqrtf(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]); if (d > 0) { d = 1.0f/d; n[0] *= d; n[1] *= d; n[2] *= d; } } return true; }
static inline void ScaleVertex(glm::vec3& v, const glm::vec3& s) { ScaleVertex(v, s.x, s.y, s.z); }
bool ZoneMap::LoadV2(FILE *f) { uint32_t data_size; if (fread(&data_size, sizeof(data_size), 1, f) != 1) { return false; } uint32_t buffer_size; if (fread(&buffer_size, sizeof(buffer_size), 1, f) != 1) { return false; } std::vector<char> data; data.resize(data_size); if (fread(&data[0], data_size, 1, f) != 1) { return false; } std::vector<char> buffer; buffer.resize(buffer_size); uint32_t v = InflateData(&data[0], data_size, &buffer[0], buffer_size); char *buf = &buffer[0]; uint32_t vert_count; uint32_t ind_count; uint32_t nc_vert_count; uint32_t nc_ind_count; uint32_t model_count; uint32_t plac_count; uint32_t plac_group_count; uint32_t tile_count; uint32_t quads_per_tile; float units_per_vertex; vert_count = *(uint32_t*)buf; buf += sizeof(uint32_t); ind_count = *(uint32_t*)buf; buf += sizeof(uint32_t); nc_vert_count = *(uint32_t*)buf; buf += sizeof(uint32_t); nc_ind_count = *(uint32_t*)buf; buf += sizeof(uint32_t); model_count = *(uint32_t*)buf; buf += sizeof(uint32_t); plac_count = *(uint32_t*)buf; buf += sizeof(uint32_t); plac_group_count = *(uint32_t*)buf; buf += sizeof(uint32_t); tile_count = *(uint32_t*)buf; buf += sizeof(uint32_t); quads_per_tile = *(uint32_t*)buf; buf += sizeof(uint32_t); units_per_vertex = *(float*)buf; buf += sizeof(float); for (uint32_t i = 0; i < vert_count; ++i) { float x; float y; float z; x = *(float*)buf; buf += sizeof(float); y = *(float*)buf; buf += sizeof(float); z = *(float*)buf; buf += sizeof(float); glm::vec3 vert(x, y, z); imp->verts.push_back(vert); } for (uint32_t i = 0; i < ind_count; ++i) { uint32_t index; index = *(uint32_t*)buf; buf += sizeof(uint32_t); imp->inds.push_back(index); } for (uint32_t i = 0; i < nc_vert_count; ++i) { float x; float y; float z; x = *(float*)buf; buf += sizeof(float); y = *(float*)buf; buf += sizeof(float); z = *(float*)buf; buf += sizeof(float); glm::vec3 vert(x, y, z); imp->nc_verts.push_back(vert); } for (uint32_t i = 0; i < nc_ind_count; ++i) { uint32_t index; index = *(uint32_t*)buf; buf += sizeof(uint32_t); imp->nc_inds.push_back(index); } std::map<std::string, std::shared_ptr<ModelEntry>> models; for (uint32_t i = 0; i < model_count; ++i) { std::shared_ptr<ModelEntry> me(new ModelEntry); std::string name = buf; buf += name.length() + 1; uint32_t vert_count = *(uint32_t*)buf; buf += sizeof(uint32_t); uint32_t poly_count = *(uint32_t*)buf; buf += sizeof(uint32_t); me->verts.resize(vert_count); for (uint32_t j = 0; j < vert_count; ++j) { float x = *(float*)buf; buf += sizeof(float); float y = *(float*)buf; buf += sizeof(float); float z = *(float*)buf; buf += sizeof(float); me->verts[j] = glm::vec3(x, y, z); } me->polys.resize(poly_count); for (uint32_t j = 0; j < poly_count; ++j) { uint32_t v1 = *(uint32_t*)buf; buf += sizeof(uint32_t); uint32_t v2 = *(uint32_t*)buf; buf += sizeof(uint32_t); uint32_t v3 = *(uint32_t*)buf; buf += sizeof(uint32_t); uint8_t vis = *(uint8_t*)buf; buf += sizeof(uint8_t); ModelEntry::Poly p; p.v1 = v1; p.v2 = v2; p.v3 = v3; p.vis = vis; me->polys[j] = p; } models[name] = me; } for (uint32_t i = 0; i < plac_count; ++i) { std::string name = buf; buf += name.length() + 1; float x = *(float*)buf; buf += sizeof(float); float y = *(float*)buf; buf += sizeof(float); float z = *(float*)buf; buf += sizeof(float); float x_rot = *(float*)buf; buf += sizeof(float); float y_rot = *(float*)buf; buf += sizeof(float); float z_rot = *(float*)buf; buf += sizeof(float); float x_scale = *(float*)buf; buf += sizeof(float); float y_scale = *(float*)buf; buf += sizeof(float); float z_scale = *(float*)buf; buf += sizeof(float); if (models.count(name) == 0) continue; auto model = models[name]; auto &mod_polys = model->polys; auto &mod_verts = model->verts; for (uint32_t j = 0; j < mod_polys.size(); ++j) { auto ¤t_poly = mod_polys[j]; auto v1 = mod_verts[current_poly.v1]; auto v2 = mod_verts[current_poly.v2]; auto v3 = mod_verts[current_poly.v3]; RotateVertex(v1, x_rot, y_rot, z_rot); RotateVertex(v2, x_rot, y_rot, z_rot); RotateVertex(v3, x_rot, y_rot, z_rot); ScaleVertex(v1, x_scale, y_scale, z_scale); ScaleVertex(v2, x_scale, y_scale, z_scale); ScaleVertex(v3, x_scale, y_scale, z_scale); TranslateVertex(v1, x, y, z); TranslateVertex(v2, x, y, z); TranslateVertex(v3, x, y, z); float t = v1.x; v1.x = v1.y; v1.y = t; t = v2.x; v2.x = v2.y; v2.y = t; t = v3.x; v3.x = v3.y; v3.y = t; if (current_poly.vis != 0) { imp->verts.push_back(v1); imp->verts.push_back(v2); imp->verts.push_back(v3); imp->inds.push_back((uint32_t)imp->verts.size() - 3); imp->inds.push_back((uint32_t)imp->verts.size() - 2); imp->inds.push_back((uint32_t)imp->verts.size() - 1); } else { imp->nc_verts.push_back(v1); imp->nc_verts.push_back(v2); imp->nc_verts.push_back(v3); imp->nc_inds.push_back((uint32_t)imp->nc_verts.size() - 3); imp->nc_inds.push_back((uint32_t)imp->nc_verts.size() - 2); imp->nc_inds.push_back((uint32_t)imp->nc_verts.size() - 1); } } } for (uint32_t i = 0; i < plac_group_count; ++i) { float x = *(float*)buf; buf += sizeof(float); float y = *(float*)buf; buf += sizeof(float); float z = *(float*)buf; buf += sizeof(float); float x_rot = *(float*)buf; buf += sizeof(float); float y_rot = *(float*)buf; buf += sizeof(float); float z_rot = *(float*)buf; buf += sizeof(float); float x_scale = *(float*)buf; buf += sizeof(float); float y_scale = *(float*)buf; buf += sizeof(float); float z_scale = *(float*)buf; buf += sizeof(float); float x_tile = *(float*)buf; buf += sizeof(float); float y_tile = *(float*)buf; buf += sizeof(float); float z_tile = *(float*)buf; buf += sizeof(float); uint32_t p_count = *(uint32_t*)buf; buf += sizeof(uint32_t); for (uint32_t j = 0; j < p_count; ++j) { std::string name = buf; buf += name.length() + 1; float p_x = *(float*)buf; buf += sizeof(float); float p_y = *(float*)buf; buf += sizeof(float); float p_z = *(float*)buf; buf += sizeof(float); float p_x_rot = *(float*)buf * 3.14159f / 180; buf += sizeof(float); float p_y_rot = *(float*)buf * 3.14159f / 180; buf += sizeof(float); float p_z_rot = *(float*)buf * 3.14159f / 180; buf += sizeof(float); float p_x_scale = *(float*)buf; buf += sizeof(float); float p_y_scale = *(float*)buf; buf += sizeof(float); float p_z_scale = *(float*)buf; buf += sizeof(float); if (models.count(name) == 0) continue; auto &model = models[name]; for (size_t k = 0; k < model->polys.size(); ++k) { auto &poly = model->polys[k]; glm::vec3 v1, v2, v3; v1 = model->verts[poly.v1]; v2 = model->verts[poly.v2]; v3 = model->verts[poly.v3]; ScaleVertex(v1, p_x_scale, p_y_scale, p_z_scale); ScaleVertex(v2, p_x_scale, p_y_scale, p_z_scale); ScaleVertex(v3, p_x_scale, p_y_scale, p_z_scale); TranslateVertex(v1, p_x, p_y, p_z); TranslateVertex(v2, p_x, p_y, p_z); TranslateVertex(v3, p_x, p_y, p_z); RotateVertex(v1, x_rot * 3.14159f / 180.0f, 0, 0); RotateVertex(v2, x_rot * 3.14159f / 180.0f, 0, 0); RotateVertex(v3, x_rot * 3.14159f / 180.0f, 0, 0); RotateVertex(v1, 0, y_rot * 3.14159f / 180.0f, 0); RotateVertex(v2, 0, y_rot * 3.14159f / 180.0f, 0); RotateVertex(v3, 0, y_rot * 3.14159f / 180.0f, 0); glm::vec3 correction(p_x, p_y, p_z); RotateVertex(correction, x_rot * 3.14159f / 180.0f, 0, 0); TranslateVertex(v1, -correction.x, -correction.y, -correction.z); TranslateVertex(v2, -correction.x, -correction.y, -correction.z); TranslateVertex(v3, -correction.x, -correction.y, -correction.z); RotateVertex(v1, p_x_rot, 0, 0); RotateVertex(v2, p_x_rot, 0, 0); RotateVertex(v3, p_x_rot, 0, 0); RotateVertex(v1, 0, -p_y_rot, 0); RotateVertex(v2, 0, -p_y_rot, 0); RotateVertex(v3, 0, -p_y_rot, 0); RotateVertex(v1, 0, 0, p_z_rot); RotateVertex(v2, 0, 0, p_z_rot); RotateVertex(v3, 0, 0, p_z_rot); TranslateVertex(v1, correction.x, correction.y, correction.z); TranslateVertex(v2, correction.x, correction.y, correction.z); TranslateVertex(v3, correction.x, correction.y, correction.z); RotateVertex(v1, 0, 0, z_rot * 3.14159f / 180.0f); RotateVertex(v2, 0, 0, z_rot * 3.14159f / 180.0f); RotateVertex(v3, 0, 0, z_rot * 3.14159f / 180.0f); ScaleVertex(v1, x_scale, y_scale, z_scale); ScaleVertex(v2, x_scale, y_scale, z_scale); ScaleVertex(v3, x_scale, y_scale, z_scale); TranslateVertex(v1, x_tile, y_tile, z_tile); TranslateVertex(v2, x_tile, y_tile, z_tile); TranslateVertex(v3, x_tile, y_tile, z_tile); TranslateVertex(v1, x, y, z); TranslateVertex(v2, x, y, z); TranslateVertex(v3, x, y, z); float t = v1.x; v1.x = v1.y; v1.y = t; t = v2.x; v2.x = v2.y; v2.y = t; t = v3.x; v3.x = v3.y; v3.y = t; if (poly.vis != 0) { imp->verts.push_back(v1); imp->verts.push_back(v2); imp->verts.push_back(v3); imp->inds.push_back((uint32_t)imp->verts.size() - 3); imp->inds.push_back((uint32_t)imp->verts.size() - 2); imp->inds.push_back((uint32_t)imp->verts.size() - 1); } else { imp->nc_verts.push_back(v1); imp->nc_verts.push_back(v2); imp->nc_verts.push_back(v3); imp->nc_inds.push_back((uint32_t)imp->nc_verts.size() - 3); imp->nc_inds.push_back((uint32_t)imp->nc_verts.size() - 2); imp->nc_inds.push_back((uint32_t)imp->nc_verts.size() - 1); } } } } uint32_t ter_quad_count = (quads_per_tile * quads_per_tile); uint32_t ter_vert_count = ((quads_per_tile + 1) * (quads_per_tile + 1)); std::vector<uint8_t> flags; std::vector<float> floats; flags.resize(ter_quad_count); floats.resize(ter_vert_count); for (uint32_t i = 0; i < tile_count; ++i) { bool flat; flat = *(bool*)buf; buf += sizeof(bool); float x; x = *(float*)buf; buf += sizeof(float); float y; y = *(float*)buf; buf += sizeof(float); if (flat) { float z; z = *(float*)buf; buf += sizeof(float); float QuadVertex1X = x; float QuadVertex1Y = y; float QuadVertex1Z = z; float QuadVertex2X = QuadVertex1X + (quads_per_tile * units_per_vertex); float QuadVertex2Y = QuadVertex1Y; float QuadVertex2Z = QuadVertex1Z; float QuadVertex3X = QuadVertex2X; float QuadVertex3Y = QuadVertex1Y + (quads_per_tile * units_per_vertex); float QuadVertex3Z = QuadVertex1Z; float QuadVertex4X = QuadVertex1X; float QuadVertex4Y = QuadVertex3Y; float QuadVertex4Z = QuadVertex1Z; uint32_t current_vert = (uint32_t)imp->verts.size() + 3; imp->verts.push_back(glm::vec3(QuadVertex1X, QuadVertex1Y, QuadVertex1Z)); imp->verts.push_back(glm::vec3(QuadVertex2X, QuadVertex2Y, QuadVertex2Z)); imp->verts.push_back(glm::vec3(QuadVertex3X, QuadVertex3Y, QuadVertex3Z)); imp->verts.push_back(glm::vec3(QuadVertex4X, QuadVertex4Y, QuadVertex4Z)); imp->inds.push_back(current_vert - 0); imp->inds.push_back(current_vert - 1); imp->inds.push_back(current_vert - 2); imp->inds.push_back(current_vert - 2); imp->inds.push_back(current_vert - 3); imp->inds.push_back(current_vert - 0); } else { //read flags for (uint32_t j = 0; j < ter_quad_count; ++j) { uint8_t f; f = *(uint8_t*)buf; buf += sizeof(uint8_t); flags[j] = f; } //read floats for (uint32_t j = 0; j < ter_vert_count; ++j) { float f; f = *(float*)buf; buf += sizeof(float); floats[j] = f; } int row_number = -1; std::map<std::tuple<float, float, float>, uint32_t> cur_verts; for (uint32_t quad = 0; quad < ter_quad_count; ++quad) { if ((quad % quads_per_tile) == 0) { ++row_number; } if (flags[quad] & 0x01) continue; float QuadVertex1X = x + (row_number * units_per_vertex); float QuadVertex1Y = y + (quad % quads_per_tile) * units_per_vertex; float QuadVertex1Z = floats[quad + row_number]; float QuadVertex2X = QuadVertex1X + units_per_vertex; float QuadVertex2Y = QuadVertex1Y; float QuadVertex2Z = floats[quad + row_number + quads_per_tile + 1]; float QuadVertex3X = QuadVertex1X + units_per_vertex; float QuadVertex3Y = QuadVertex1Y + units_per_vertex; float QuadVertex3Z = floats[quad + row_number + quads_per_tile + 2]; float QuadVertex4X = QuadVertex1X; float QuadVertex4Y = QuadVertex1Y + units_per_vertex; float QuadVertex4Z = floats[quad + row_number + 1]; uint32_t i1, i2, i3, i4; std::tuple<float, float, float> t = std::make_tuple(QuadVertex1X, QuadVertex1Y, QuadVertex1Z); auto iter = cur_verts.find(t); if (iter != cur_verts.end()) { i1 = iter->second; } else { i1 = (uint32_t)imp->verts.size(); imp->verts.push_back(glm::vec3(QuadVertex1X, QuadVertex1Y, QuadVertex1Z)); cur_verts[std::make_tuple(QuadVertex1X, QuadVertex1Y, QuadVertex1Z)] = i1; } t = std::make_tuple(QuadVertex2X, QuadVertex2Y, QuadVertex2Z); iter = cur_verts.find(t); if (iter != cur_verts.end()) { i2 = iter->second; } else { i2 = (uint32_t)imp->verts.size(); imp->verts.push_back(glm::vec3(QuadVertex2X, QuadVertex2Y, QuadVertex2Z)); cur_verts[std::make_tuple(QuadVertex2X, QuadVertex2Y, QuadVertex2Z)] = i2; } t = std::make_tuple(QuadVertex3X, QuadVertex3Y, QuadVertex3Z); iter = cur_verts.find(t); if (iter != cur_verts.end()) { i3 = iter->second; } else { i3 = (uint32_t)imp->verts.size(); imp->verts.push_back(glm::vec3(QuadVertex3X, QuadVertex3Y, QuadVertex3Z)); cur_verts[std::make_tuple(QuadVertex3X, QuadVertex3Y, QuadVertex3Z)] = i3; } t = std::make_tuple(QuadVertex4X, QuadVertex4Y, QuadVertex4Z); iter = cur_verts.find(t); if (iter != cur_verts.end()) { i4 = iter->second; } else { i4 = (uint32_t)imp->verts.size(); imp->verts.push_back(glm::vec3(QuadVertex4X, QuadVertex4Y, QuadVertex4Z)); cur_verts[std::make_tuple(QuadVertex4X, QuadVertex4Y, QuadVertex4Z)] = i4; } imp->inds.push_back(i4); imp->inds.push_back(i3); imp->inds.push_back(i2); imp->inds.push_back(i2); imp->inds.push_back(i1); imp->inds.push_back(i4); } } } float t; for(auto &v : imp->verts) { t = v.y; v.y = v.z; v.z = t; } for(auto &vert : imp->verts) { if(vert.x < imp->min.x) { imp->min.x = vert.x; } if(vert.y < imp->min.y && vert.y > -15000) { imp->min.y = vert.y; } if(vert.z < imp->min.z) { imp->min.z = vert.z; } if(vert.x > imp->max.x) { imp->max.x = vert.x; } if(vert.y > imp->max.y) { imp->max.y = vert.y; } if(vert.z > imp->max.z) { imp->max.z = vert.z; } } for(auto &v : imp->nc_verts) { t = v.y; v.y = v.z; v.z = t; } for(auto &vert : imp->nc_verts) { if(vert.x < imp->nc_min.x) { imp->nc_min.x = vert.x; } if(vert.y < imp->nc_min.y) { imp->nc_min.y = vert.y; } if(vert.z < imp->nc_min.z) { imp->nc_min.z = vert.z; } if(vert.x > imp->nc_max.x) { imp->nc_max.x = vert.x; } if(vert.y > imp->nc_max.y) { imp->nc_max.y = vert.y; } if(vert.z > imp->nc_max.z) { imp->nc_max.z = vert.z; } } return true; }