11#include " ModelSingleton.hpp"
22
3+ #include < cstddef>
4+ #include < cstdint>
35#include < numbers>
46
57#include < godot_cpp/variant/utility_functions.hpp>
911#include " openvic-extension/singletons/GameSingleton.hpp"
1012#include " openvic-extension/utility/ClassBindings.hpp"
1113#include " openvic-extension/utility/Utilities.hpp"
14+ #include " openvic-extension/utility/XSMLoader.hpp"
15+ #include " godot_cpp/classes/global_constants.hpp"
16+ #include " godot_cpp/classes/node3d.hpp"
17+ #include " godot_cpp/classes/resource_loader.hpp"
18+ #include " godot_cpp/classes/shader_material.hpp"
19+ #include " godot_cpp/variant/string_name.hpp"
1220
1321using namespace godot ;
1422using namespace OpenVic ;
@@ -19,6 +27,11 @@ void ModelSingleton::_bind_methods() {
1927 OV_BIND_METHOD (ModelSingleton::get_cultural_helmet_model, { " culture" });
2028 OV_BIND_METHOD (ModelSingleton::get_flag_model, { " floating" });
2129 OV_BIND_METHOD (ModelSingleton::get_buildings);
30+ OV_BIND_METHOD (ModelSingleton::get_xsm_animation,{ " animation_name" });
31+ OV_BIND_METHOD (ModelSingleton::get_xac_model,{ " model_name" , " is_unit" });
32+ OV_BIND_METHOD (ModelSingleton::setup_flag_shader);
33+ OV_BIND_METHOD (ModelSingleton::set_scroll_material_texture, {" texture_name" });
34+ OV_BIND_METHOD (ModelSingleton::set_unit_material_texture, {" type" , " texture_name" });
2235}
2336
2437ModelSingleton* ModelSingleton::get_singleton () {
@@ -481,3 +494,143 @@ TypedArray<Dictionary> ModelSingleton::get_buildings() {
481494
482495 return ret;
483496}
497+
498+ Ref<Animation> ModelSingleton::get_xsm_animation (String source_file) {
499+ const xsm_map_t ::const_iterator it = xsm_cache.find (source_file);
500+ if (it != xsm_cache.end ()) {
501+ return it->second ;
502+ }
503+
504+ GameSingleton const * game_singleton = GameSingleton::get_singleton ();
505+ ERR_FAIL_NULL_V (game_singleton, {});
506+
507+ String path = game_singleton->lookup_file_path (source_file);
508+
509+ Ref<Animation> anim = XsmLoader ().load_xsm_animation (FileAccess::open (path, FileAccess::READ ));
510+ xsm_cache.emplace (source_file,anim);
511+ return anim;
512+ }
513+
514+ Node3D* ModelSingleton::get_xac_model (String source_file, bool is_unit) {
515+ const xac_map_t ::const_iterator it = xac_cache.find (source_file);
516+ if (it != xac_cache.end ()) {
517+ Node3D* unit = (Node3D*)it->second ->duplicate ();
518+ if (unit->has_method (" unit_init" )){
519+ unit->call (" unit_init" , true );
520+ }
521+ return unit;
522+ }
523+
524+ GameSingleton const * game_singleton = GameSingleton::get_singleton ();
525+ ERR_FAIL_NULL_V (game_singleton, {});
526+
527+ String path = game_singleton->lookup_file_path (source_file);
528+ Node3D* node = XacLoader ().load_xac_model (FileAccess::open (path, FileAccess::READ ),is_unit);
529+ xac_cache.emplace (source_file,node);
530+
531+ // if we return the "prototype" in the cache, then it will get scale by 1/256, and then all subsequent units
532+ // duplicated from the cache will get effectively scaled by 1/256*1/256, among other problems.
533+ Node3D* unit = (Node3D*)node->duplicate ();
534+ if (unit->has_method (" unit_init" )){
535+ unit->call (" unit_init" , true );
536+ }
537+ return unit;
538+ }
539+
540+ Error ModelSingleton::setup_flag_shader () {
541+ Error result = OK ;
542+ GameSingleton const * game_singleton = GameSingleton::get_singleton ();
543+ ERR_FAIL_NULL_V (game_singleton, {});
544+
545+ static const StringName Param_flag_dimensions = " flag_dims" ;
546+ static const StringName Param_flag_texture_sheet = " texture_flag_sheet_diffuse" ;
547+ ResourceLoader* loader = ResourceLoader::get_singleton ();
548+ static const Ref<ShaderMaterial> flag_shader = loader->load (" res://src/Game/Model/flag_mat.tres" );
549+
550+ flag_shader->set_shader_parameter (Param_flag_dimensions, game_singleton->get_flag_dims ());
551+ flag_shader->set_shader_parameter (Param_flag_texture_sheet, game_singleton->get_flag_sheet_texture ());
552+ return result;
553+ }
554+
555+ static void pushback_shader_array (Ref<ShaderMaterial> shader, String property, Variant value) {
556+ Array arr = shader->get_shader_parameter (property);
557+ arr.push_back (value);
558+ shader->set_shader_parameter (property, arr);
559+ }
560+
561+ Ref<ShaderMaterial> ModelSingleton::get_unit_shader () {
562+ if (unit_shader.is_null ()) {
563+ ResourceLoader* loader = ResourceLoader::get_singleton ();
564+ unit_shader = loader->load (" res://src/Game/Model/unit_colours_mat.tres" );
565+ }
566+ return unit_shader;
567+ }
568+
569+ Ref<ShaderMaterial> ModelSingleton::get_scroll_shader () {
570+ if (scroll_shader.is_null ()) {
571+ ResourceLoader* loader = ResourceLoader::get_singleton ();
572+ scroll_shader = loader->load (" res://src/Game/Model/scrolling_mat.tres" );
573+ }
574+ return scroll_shader;
575+ }
576+
577+ // TODO: put this back, 64 is likely needed because of names being added twice
578+ // (due to 2 loaders operating)
579+ static constexpr uint32_t MAX_UNIT_TEXTURES = 64 ;
580+
581+ int32_t ModelSingleton::set_unit_material_texture (int32_t type, String texture_name) {// MAP_TYPE::Values
582+ shader_array_index_map_t & map = type==2 ? diffuse_texture_index_map : specular_texture_index_map; // OpenVic::MAP_TYPE::DIFFUSE
583+ const shader_array_index_map_t ::const_iterator it = map.find (texture_name);
584+ if (it != map.end ()) {
585+ // UtilityFunctions::print(
586+ // vformat("cached texture: %s type: %d, index %d", texture_name, type, it->second)
587+ // );
588+ return it->second ; // return the index
589+ }
590+
591+ int32_t index = map.size ();
592+ map.emplace (texture_name,index);
593+ if (map.size () >= MAX_UNIT_TEXTURES ) {
594+ Logger::error (" Number of textures exceeded max supported by a shader!" );
595+ return 0 ;
596+ }
597+
598+ // Parameters for the default model shader
599+ static const StringName Param_texture_diffuse = " texture_diffuse" ;
600+ // red channel is specular, green and blue are nation colours
601+ static const StringName Param_texture_nation_colors_mask = " texture_nation_colors_mask" ;
602+ // static const StringName Param_texture_shadow = "texture_shadow";
603+ String shader_param = type==2 ? Param_texture_diffuse : Param_texture_nation_colors_mask; // OpenVic::MAP_TYPE::DIFFUSE
604+
605+ pushback_shader_array (get_unit_shader (), shader_param, XacLoader::get_model_texture (texture_name));
606+
607+ return index;
608+ }
609+
610+ int32_t ModelSingleton::set_scroll_material_texture (String texture_name) {
611+ const shader_array_index_map_t ::const_iterator it = scroll_index_map.find (texture_name);
612+ if (it != scroll_index_map.end ()) {
613+ return it->second ; // return the index
614+ }
615+
616+ scroll_index_map.emplace (texture_name,scroll_index_map.size ());
617+ if (scroll_index_map.size () >= MAX_UNIT_TEXTURES ) {
618+ Logger::error (" Number of textures exceeded max supported by a shader!" );
619+ return 0 ;
620+ }
621+
622+ static const StringName Param_Scroll_texture_diffuse = " scroll_texture_diffuse" ;
623+ static const StringName Param_Scroll_factor = " scroll_factor" ;
624+
625+ pushback_shader_array (get_scroll_shader (), Param_Scroll_texture_diffuse, XacLoader::get_model_texture (texture_name));
626+
627+ float scroll_factor = 0.0 ;
628+ static const StringName tracks = " TexAnim" ;
629+ static const StringName smoke = " Smoke" ;
630+ if (texture_name == tracks) { scroll_factor = 2.5 ; }
631+ else if (texture_name == smoke) { scroll_factor = 0.3 ; }
632+
633+ pushback_shader_array (get_scroll_shader (), Param_Scroll_factor, scroll_factor);
634+
635+ return scroll_index_map[texture_name];
636+ }
0 commit comments