42 std::string full_filepath;
46 full_filepath = ASSETS_PATH + std::string(
"/custom/models/") + filepath +
".json";
50 full_filepath = ASSETS_PATH + std::string(
"/minecraft/models/") + filepath +
".json";
53 bool error = filepath ==
"";
60 std::ifstream file(full_filepath);
64 catch (
const std::runtime_error& e)
66 LOG_ERROR(
"Error reading model file " << full_filepath <<
'\n' << e.what());
77 faces = std::vector<FaceDescriptor>();
78 for (
int i = 0; i < 6; ++i)
85 faces.push_back(current_face);
98#if PROTOCOL_VERSION > 578
100 std::string model_name = obj[
"parent"].
get_string();
103 model_name = model_name.substr(10);
107 const Model& parent_model =
GetModel(obj[
"parent"].get_string(), custom);
119 if (obj.
contains(
"ambientocclusion"))
128 if (obj.
contains(
"textures_base_size"))
130 for (
const auto& [key, val] : obj[
"textures_base_size"].
get_object())
132 textures_base_size[key] = std::pair<int, int>(val[0].get_number<int>(), val[1].get_number<int>());
138 for (
const auto& [key, val] : obj[
"textures"].
get_object())
140#if PROTOCOL_VERSION > 578
142#if PROTOCOL_VERSION < 775
143 std::string texture_name = val.get_string();
145 std::string texture_name;
148 texture_name = val.get_string();
150 else if (val.is_object() && val.contains(
"sprite"))
152 texture_name = val[
"sprite"].get_string();
156 throw std::runtime_error(
"Unknown block definition json format for " + filepath);
161 texture_name = texture_name.substr(10);
164 const std::string& texture_name = val.get_string();
167 if (texture_name.rfind(
"#", 0) == 0)
182 for (
const auto& element : obj[
"elements"].
get_array())
185 std::vector<FaceDescriptor> current_element;
188 int start_x, start_y, start_z;
189 int end_x, end_y, end_z;
191 if (element.contains(
"from"))
193 start_x = element[
"from"][0].get_number<
int>();
194 start_y = element[
"from"][1].get_number<
int>();
195 start_z = element[
"from"][2].get_number<
int>();
198 if (element.contains(
"to"))
200 end_x = element[
"to"][0].get_number<
int>();
201 end_y = element[
"to"][1].get_number<
int>();
202 end_z = element[
"to"][2].get_number<
int>();
205 colliders.insert(
AABB(
Vector3<double>(start_x + end_x, start_y + end_y, start_z + end_z) / 2.0 / 16.0,
Vector3<double>(std::abs(end_x - start_x), std::abs(end_y - start_y), std::abs(end_z - start_z)) / 2.0 / 16.0));
208 if (element.contains(
"rotation"))
210 float origin_x, origin_y, origin_z;
211 origin_x = element[
"rotation"][
"origin"][0].get_number<
float>();
212 origin_y = element[
"rotation"][
"origin"][1].get_number<
float>();
213 origin_z = element[
"rotation"][
"origin"][2].get_number<
float>();
217 const float angle = element[
"rotation"][
"angle"].get_number<
float>();
219 if (element[
"rotation"][
"axis"].get_string() ==
"x")
223 else if (element[
"rotation"][
"axis"].get_string() ==
"y")
227 else if (element[
"rotation"][
"axis"].get_string() ==
"z")
233 bool rescale =
false;
234 if (element[
"rotation"].contains(
"rescale"))
236 rescale = element[
"rotation"][
"rescale"].get<
bool>();
241 float scale_factor = std::abs(1.0f / (std::cos(angle * 3.14159f / 180.0f)));
242 if (element[
"rotation"][
"axis"].get_string() ==
"x")
246 else if (element[
"rotation"][
"axis"].get_string() ==
"y")
250 else if (element[
"rotation"][
"axis"].get_string() ==
"z")
257 if (element.contains(
"shade"))
262 if (element.contains(
"faces"))
264 for (
const auto& [key, face_params] : element[
"faces"].get_object())
271 else if (key ==
"up")
275 else if (key ==
"north")
279 else if (key ==
"south")
283 else if (key ==
"east")
287 else if (key ==
"west")
292 if (face_params.contains(
"uv"))
345 if (face_params.contains(
"texture"))
347 const std::string& texture_name = face_params[
"texture"].get_string();
355 if (face_params.contains(
"cullface"))
357 const std::string& value = face_params[
"cullface"].get_string();
362 else if (value ==
"up")
366 else if (value ==
"north")
370 else if (value ==
"south")
374 else if (value ==
"west")
378 else if (value ==
"east")
392 if (face_params.contains(
"rotation"))
397 if (face_params.contains(
"tintindex"))
406 current_element.push_back(current_face);
411 float center_x = (end_x + start_x) / 2.0f;
412 float center_y = (end_y + start_y) / 2.0f;
413 float center_z = (end_z + start_z) / 2.0f;
415 if (center_x != 8.0f || center_y != 8.0f || center_z != 8.0f)
424 for (
int m = 0; m < current_element.size(); ++m)
426 for (
int n = 0; n < element_global_transformations.
scales.size(); ++n)
428 current_element[m].transformations.scales.push_back(element_global_transformations.
scales[n]);
430 for (
int n = 0; n < element_global_transformations.
rotations.size(); ++n)
432 current_element[m].transformations.rotations.push_back(element_global_transformations.
rotations[n]);
434 for (
int n = 0; n < element_global_transformations.
translations.size(); ++n)
436 current_element[m].transformations.translations.push_back(element_global_transformations.
translations[n]);
438 current_element[m].face =
Renderer::Face(current_element[m].transformations, current_element[m].orientation);
442 faces.insert(
faces.end(), current_element.begin(), current_element.end());
448 bool has_changed =
true;
453 for (
int i =
static_cast<int>(
faces.size()) - 1; i > -1; --i)
456 if (
faces[i].texture_names[0].rfind(
"#overlay", 0) == 0)
458 int matching_index = -1;
459 for (
int j = 0; j <
faces.size(); ++j)
469 if (matching_index != -1)
471 faces[matching_index].texture_names.push_back(
faces[i].texture_names[0]);
472 faces[matching_index].use_tintindexes.push_back(
faces[i].use_tintindexes[0]);
478 for (
int s = 0; s <
faces[i].texture_names.size(); ++s)
480 std::string variable_name =
faces[i].texture_names[s];
481 while (variable_name.rfind(
"#", 0) == 0 && variable_name !=
textures_variables[variable_name])
486 faces[i].texture_names[s] = variable_name;
495 for (
size_t i = 0; i <
faces.size(); ++i)
497 if (
faces[i].texture_names.size() == 0)
505 faces[i].transformations.offset_x1 *= 16.0f / it->second.first;
506 faces[i].transformations.offset_y1 *= 16.0f / it->second.second;
507 faces[i].transformations.offset_x2 *= 16.0f / it->second.first;
508 faces[i].transformations.offset_y2 *= 16.0f / it->second.second;
522 faces = std::vector<FaceDescriptor>(6);
523 for (
int i = 0; i < 6; ++i)
526 faces[i].texture_names = { texture };
528 faces[i].use_tintindexes = {
false };
530 faces[i].transformations.scales.push_back(std::make_shared<Renderer::Scale>(0.5f, 0.5f *
static_cast<float>(height), 0.5f));
531 faces[i].transformations.translations.push_back(std::make_shared<Renderer::Translation>(0.0f, 0.5f *
static_cast<float>(height) - 0.5f, 0.0f));
533 faces[i].transformations.rotation = 0;
535 switch (
faces[i].orientation)
538 faces[i].transformations.offset_x1 = 0.0f;
539 faces[i].transformations.offset_y1 = 0.0f;
540 faces[i].transformations.offset_x2 = 16.0f;
541 faces[i].transformations.offset_y2 = 16.0f;
544 faces[i].transformations.offset_x1 = 0.0f;
545 faces[i].transformations.offset_y1 = 0.0f;
546 faces[i].transformations.offset_x2 = 16.0f;
547 faces[i].transformations.offset_y2 = 16.0f;
550 faces[i].transformations.offset_x1 = 0.0f;
551 faces[i].transformations.offset_y1 = 16.0f * (1.0f -
static_cast<float>(height));
552 faces[i].transformations.offset_x2 = 16.0f;
553 faces[i].transformations.offset_y2 = 16.0f;
556 faces[i].transformations.offset_x1 = 0.0f;
557 faces[i].transformations.offset_y1 = 16.0f * (1.0f -
static_cast<float>(height));
558 faces[i].transformations.offset_x2 = 16.0f;
559 faces[i].transformations.offset_y2 = 16.0f;
562 faces[i].transformations.offset_x1 = 0.0f;
563 faces[i].transformations.offset_y1 = 16.0f * (1.0f -
static_cast<float>(height));
564 faces[i].transformations.offset_x2 = 16.0f;
565 faces[i].transformations.offset_y2 = 16.0f;
568 faces[i].transformations.offset_x1 = 0.0f;
569 faces[i].transformations.offset_y1 = 16.0f * (1.0f -
static_cast<float>(height));
570 faces[i].transformations.offset_x2 = 16.0f;
571 faces[i].transformations.offset_y2 = 16.0f;