41 std::string full_filepath;
45 full_filepath = ASSETS_PATH + std::string(
"/custom/models/") + filepath +
".json";
49 full_filepath = ASSETS_PATH + std::string(
"/minecraft/models/") + filepath +
".json";
52 bool error = filepath ==
"";
59 std::ifstream file(full_filepath);
63 catch (
const std::runtime_error& e)
65 LOG_ERROR(
"Error reading model file " << full_filepath <<
'\n' << e.what());
76 faces = std::vector<FaceDescriptor>();
77 for (
int i = 0; i < 6; ++i)
84 faces.push_back(current_face);
97#if PROTOCOL_VERSION > 578
99 std::string model_name = obj[
"parent"].
get_string();
102 model_name = model_name.substr(10);
106 const Model& parent_model =
GetModel(obj[
"parent"].get_string(), custom);
118 if (obj.
contains(
"ambientocclusion"))
127 if (obj.
contains(
"textures_base_size"))
129 for (
const auto& [key, val] : obj[
"textures_base_size"].
get_object())
131 textures_base_size[key] = std::pair<int, int>(val[0].get_number<int>(), val[1].get_number<int>());
137 for (
const auto& [key, val] : obj[
"textures"].
get_object())
139#if PROTOCOL_VERSION > 578
141 std::string texture_name = val.get_string();
144 texture_name = texture_name.substr(10);
147 const std::string& texture_name = val.get_string();
150 if (val.get_string().rfind(
"#", 0) == 0)
165 for (
const auto& element : obj[
"elements"].
get_array())
168 std::vector<FaceDescriptor> current_element;
171 int start_x, start_y, start_z;
172 int end_x, end_y, end_z;
174 if (element.contains(
"from"))
176 start_x = element[
"from"][0].get_number<
int>();
177 start_y = element[
"from"][1].get_number<
int>();
178 start_z = element[
"from"][2].get_number<
int>();
181 if (element.contains(
"to"))
183 end_x = element[
"to"][0].get_number<
int>();
184 end_y = element[
"to"][1].get_number<
int>();
185 end_z = element[
"to"][2].get_number<
int>();
188 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));
191 if (element.contains(
"rotation"))
193 float origin_x, origin_y, origin_z;
194 origin_x = element[
"rotation"][
"origin"][0].get_number<
float>();
195 origin_y = element[
"rotation"][
"origin"][1].get_number<
float>();
196 origin_z = element[
"rotation"][
"origin"][2].get_number<
float>();
200 const float angle = element[
"rotation"][
"angle"].get_number<
float>();
202 if (element[
"rotation"][
"axis"].get_string() ==
"x")
206 else if (element[
"rotation"][
"axis"].get_string() ==
"y")
210 else if (element[
"rotation"][
"axis"].get_string() ==
"z")
216 bool rescale =
false;
217 if (element[
"rotation"].contains(
"rescale"))
219 rescale = element[
"rotation"][
"rescale"].get<
bool>();
224 float scale_factor = std::abs(1.0f / (std::cos(angle * 3.14159f / 180.0f)));
225 if (element[
"rotation"][
"axis"].get_string() ==
"x")
229 else if (element[
"rotation"][
"axis"].get_string() ==
"y")
233 else if (element[
"rotation"][
"axis"].get_string() ==
"z")
240 if (element.contains(
"shade"))
245 if (element.contains(
"faces"))
247 for (
const auto& [key, face_params] : element[
"faces"].get_object())
254 else if (key ==
"up")
258 else if (key ==
"north")
262 else if (key ==
"south")
266 else if (key ==
"east")
270 else if (key ==
"west")
275 if (face_params.contains(
"uv"))
328 if (face_params.contains(
"texture"))
330 const std::string& texture_name = face_params[
"texture"].get_string();
338 if (face_params.contains(
"cullface"))
340 const std::string& value = face_params[
"cullface"].get_string();
345 else if (value ==
"up")
349 else if (value ==
"north")
353 else if (value ==
"south")
357 else if (value ==
"west")
361 else if (value ==
"east")
375 if (face_params.contains(
"rotation"))
380 if (face_params.contains(
"tintindex"))
389 current_element.push_back(current_face);
394 float center_x = (end_x + start_x) / 2.0f;
395 float center_y = (end_y + start_y) / 2.0f;
396 float center_z = (end_z + start_z) / 2.0f;
398 if (center_x != 8.0f || center_y != 8.0f || center_z != 8.0f)
407 for (
int m = 0; m < current_element.size(); ++m)
409 for (
int n = 0; n < element_global_transformations.
scales.size(); ++n)
411 current_element[m].transformations.scales.push_back(element_global_transformations.
scales[n]);
413 for (
int n = 0; n < element_global_transformations.
rotations.size(); ++n)
415 current_element[m].transformations.rotations.push_back(element_global_transformations.
rotations[n]);
417 for (
int n = 0; n < element_global_transformations.
translations.size(); ++n)
419 current_element[m].transformations.translations.push_back(element_global_transformations.
translations[n]);
421 current_element[m].face =
Renderer::Face(current_element[m].transformations, current_element[m].orientation);
425 faces.insert(
faces.end(), current_element.begin(), current_element.end());
431 bool has_changed =
true;
436 for (
int i =
static_cast<int>(
faces.size()) - 1; i > -1; --i)
439 if (
faces[i].texture_names[0].rfind(
"#overlay", 0) == 0)
441 int matching_index = -1;
442 for (
int j = 0; j <
faces.size(); ++j)
452 if (matching_index != -1)
454 faces[matching_index].texture_names.push_back(
faces[i].texture_names[0]);
455 faces[matching_index].use_tintindexes.push_back(
faces[i].use_tintindexes[0]);
461 for (
int s = 0; s <
faces[i].texture_names.size(); ++s)
463 std::string variable_name =
faces[i].texture_names[s];
464 while (variable_name.rfind(
"#", 0) == 0 && variable_name !=
textures_variables[variable_name])
469 faces[i].texture_names[s] = variable_name;
478 for (
size_t i = 0; i <
faces.size(); ++i)
480 if (
faces[i].texture_names.size() == 0)
488 faces[i].transformations.offset_x1 *= 16.0f / it->second.first;
489 faces[i].transformations.offset_y1 *= 16.0f / it->second.second;
490 faces[i].transformations.offset_x2 *= 16.0f / it->second.first;
491 faces[i].transformations.offset_y2 *= 16.0f / it->second.second;
505 faces = std::vector<FaceDescriptor>(6);
506 for (
int i = 0; i < 6; ++i)
509 faces[i].texture_names = { texture };
511 faces[i].use_tintindexes = {
false };
513 faces[i].transformations.scales.push_back(std::make_shared<Renderer::Scale>(0.5f, 0.5f *
static_cast<float>(height), 0.5f));
514 faces[i].transformations.translations.push_back(std::make_shared<Renderer::Translation>(0.0f, 0.5f *
static_cast<float>(height) - 0.5f, 0.0f));
516 faces[i].transformations.rotation = 0;
518 switch (
faces[i].orientation)
521 faces[i].transformations.offset_x1 = 0.0f;
522 faces[i].transformations.offset_y1 = 0.0f;
523 faces[i].transformations.offset_x2 = 16.0f;
524 faces[i].transformations.offset_y2 = 16.0f;
527 faces[i].transformations.offset_x1 = 0.0f;
528 faces[i].transformations.offset_y1 = 0.0f;
529 faces[i].transformations.offset_x2 = 16.0f;
530 faces[i].transformations.offset_y2 = 16.0f;
533 faces[i].transformations.offset_x1 = 0.0f;
534 faces[i].transformations.offset_y1 = 16.0f * (1.0f -
static_cast<float>(height));
535 faces[i].transformations.offset_x2 = 16.0f;
536 faces[i].transformations.offset_y2 = 16.0f;
539 faces[i].transformations.offset_x1 = 0.0f;
540 faces[i].transformations.offset_y1 = 16.0f * (1.0f -
static_cast<float>(height));
541 faces[i].transformations.offset_x2 = 16.0f;
542 faces[i].transformations.offset_y2 = 16.0f;
545 faces[i].transformations.offset_x1 = 0.0f;
546 faces[i].transformations.offset_y1 = 16.0f * (1.0f -
static_cast<float>(height));
547 faces[i].transformations.offset_x2 = 16.0f;
548 faces[i].transformations.offset_y2 = 16.0f;
551 faces[i].transformations.offset_x1 = 0.0f;
552 faces[i].transformations.offset_y1 = 16.0f * (1.0f -
static_cast<float>(height));
553 faces[i].transformations.offset_x2 = 16.0f;
554 faces[i].transformations.offset_y2 = 16.0f;