Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load xac and xsm with cpp #380

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions extension/doc_classes/ModelSingleton.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,37 @@
<description>
</description>
</method>
<method name="get_xac_model">
<return type="Node3D" />
<param index="0" name="model_name" type="String" />
<description>
Gets the animation from an internal cache or file system using the provided file path.
</description>
</method>
<method name="get_xsm_animation">
<return type="Animation" />
<param index="0" name="animation_name" type="String" />
<description>
Gets the animation from an internal cache or file system using the provided file path.
</description>
</method>
<method name="set_scroll_material_texture">
<return type="int" />
<param index="0" name="texture_name" type="String" />
<description>
</description>
</method>
<method name="set_unit_material_texture">
<return type="int" />
<param index="0" name="type" type="int" />
<param index="1" name="texture_name" type="String" />
<description>
</description>
</method>
<method name="setup_flag_shader">
<return type="int" enum="Error" />
<description>
</description>
</method>
</methods>
</class>
160 changes: 160 additions & 0 deletions extension/src/openvic-extension/singletons/ModelSingleton.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "ModelSingleton.hpp"

#include <cstddef>
#include <cstdint>
#include <numbers>

#include <godot_cpp/variant/utility_functions.hpp>
Expand All @@ -9,6 +11,11 @@
#include "openvic-extension/singletons/GameSingleton.hpp"
#include "openvic-extension/utility/ClassBindings.hpp"
#include "openvic-extension/utility/Utilities.hpp"
#include "godot_cpp/classes/global_constants.hpp"
#include "godot_cpp/classes/node3d.hpp"
#include "godot_cpp/classes/resource_loader.hpp"
#include "godot_cpp/classes/shader_material.hpp"
#include "godot_cpp/variant/string_name.hpp"

using namespace godot;
using namespace OpenVic;
Expand All @@ -19,6 +26,11 @@ void ModelSingleton::_bind_methods() {
OV_BIND_METHOD(ModelSingleton::get_cultural_helmet_model, { "culture" });
OV_BIND_METHOD(ModelSingleton::get_flag_model, { "floating" });
OV_BIND_METHOD(ModelSingleton::get_buildings);
OV_BIND_METHOD(ModelSingleton::get_xsm_animation,{ "animation_name" });
OV_BIND_METHOD(ModelSingleton::get_xac_model,{ "model_name" });
OV_BIND_METHOD(ModelSingleton::setup_flag_shader);
OV_BIND_METHOD(ModelSingleton::set_scroll_material_texture, {"texture_name"});
OV_BIND_METHOD(ModelSingleton::set_unit_material_texture, {"type", "texture_name"});
}

ModelSingleton* ModelSingleton::get_singleton() {
Expand Down Expand Up @@ -481,3 +493,151 @@ TypedArray<Dictionary> ModelSingleton::get_buildings() {

return ret;
}

Ref<Animation> ModelSingleton::get_xsm_animation(String source_file) {
const xsm_map_t::const_iterator it = xsm_cache.find(source_file);
if(it != xsm_cache.end()) {
return it->second;
}

GameSingleton const* game_singleton = GameSingleton::get_singleton();
ERR_FAIL_NULL_V(game_singleton, {});

String path = game_singleton->lookup_file_path(source_file);

//Logger::info("Load XSM Animation from file: ",Utilities::godot_to_std_string(source_file));

Ref<Animation> anim = _load_xsm_animation(FileAccess::open(path, FileAccess::READ));
xsm_cache.emplace(source_file,anim);
return anim;
}

Node3D* ModelSingleton::get_xac_model(String source_file) {
const xac_map_t::const_iterator it = xac_cache.find(source_file);
if(it != xac_cache.end()) {
Node3D* unit = (Node3D*)it->second->duplicate();
unit->call("unit_init", true);
//if(unit->get_script()->) {

//}
return unit;
//return (Node3D*)it->second->duplicate();
}

GameSingleton const* game_singleton = GameSingleton::get_singleton();
ERR_FAIL_NULL_V(game_singleton, {});

String path = game_singleton->lookup_file_path(source_file);

Logger::info("Load XAC Model from file: ",Utilities::godot_to_std_string(source_file));

Node3D* node = XacLoader()._load_xac_model(FileAccess::open(path, FileAccess::READ));
xac_cache.emplace(source_file,node);

//if we return the "prototype" in the cache, then it will get scale by 1/256, and then all subsequent units
//duplicated from the cache will get effectively scaled by 1/256*1/256, among other problems.
Node3D* unit = (Node3D*)node->duplicate();
unit->call("unit_init", true);
return unit;
}

Error ModelSingleton::setup_flag_shader() {
godot::Error result = godot::OK;
GameSingleton const* game_singleton = GameSingleton::get_singleton();
ERR_FAIL_NULL_V(game_singleton, {});

static const godot::StringName Param_flag_dimensions = "flag_dims";
static const godot::StringName Param_flag_texture_sheet = "texture_flag_sheet_diffuse";
godot::ResourceLoader* loader = godot::ResourceLoader::get_singleton();
static const godot::Ref<godot::ShaderMaterial> flag_shader = loader->load("res://src/Game/Model/flag_mat.tres");

flag_shader->set_shader_parameter(Param_flag_dimensions, game_singleton->get_flag_dims());
flag_shader->set_shader_parameter(Param_flag_texture_sheet, game_singleton->get_flag_sheet_texture());
return result;
}

static void pushback_shader_array(godot::Ref<godot::ShaderMaterial> shader, godot::String property, godot::Variant value) {
godot::Array arr = shader->get_shader_parameter(property);
arr.push_back(value);
shader->set_shader_parameter(property, arr);
}

Ref<ShaderMaterial> ModelSingleton::get_unit_shader() {
if(unit_shader.is_null()) {
godot::ResourceLoader* loader = godot::ResourceLoader::get_singleton();
unit_shader = loader->load("res://src/Game/Model/unit_colours_mat.tres");
}
return unit_shader;
}

Ref<ShaderMaterial> ModelSingleton::get_scroll_shader() {
if(scroll_shader.is_null()) {
godot::ResourceLoader* loader = godot::ResourceLoader::get_singleton();
scroll_shader = loader->load("res://src/Game/Model/scrolling_mat.tres");
}
return scroll_shader;
}

//TODO: put this back, 64 is likely needed because of names being added twice
// (due to 2 loaders operating)
static constexpr uint32_t MAX_UNIT_TEXTURES = 32;

int32_t ModelSingleton::set_unit_material_texture(int32_t type, godot::String texture_name) {//MAP_TYPE::Values
shader_array_index_map_t& map = type==2 ? diffuse_texture_index_map : specular_texture_index_map; //OpenVic::MAP_TYPE::DIFFUSE
const shader_array_index_map_t::const_iterator it = map.find(texture_name);
if(it != map.end()) {
//godot::UtilityFunctions::print(
// godot::vformat("cached texture: %s type: %d, index %d", texture_name, type, it->second)
//);
return it->second; //return the index
}

int32_t index = map.size();
map.emplace(texture_name,index);
if (map.size() >= MAX_UNIT_TEXTURES) {
Logger::error("Number of textures exceeded max supported by a shader!");
return 0;
}

// Parameters for the default model shader
static const godot::StringName Param_texture_diffuse = "texture_diffuse";
//red channel is specular, green and blue are nation colours
static const godot::StringName Param_texture_nation_colors_mask = "texture_nation_colors_mask";
//static const godot::StringName Param_texture_shadow = "texture_shadow";
String shader_param = type==2 ? Param_texture_diffuse : Param_texture_nation_colors_mask; //OpenVic::MAP_TYPE::DIFFUSE

//godot::UtilityFunctions::print(
// godot::vformat("texture: %s type: %d, index %d", texture_name, type, index)
//);
pushback_shader_array(get_unit_shader(), shader_param, XacLoader::get_model_texture(texture_name));

return index;
}

int32_t ModelSingleton::set_scroll_material_texture(godot::String texture_name) {
const shader_array_index_map_t::const_iterator it = scroll_index_map.find(texture_name);
if(it != scroll_index_map.end()) {
return it->second; //return the index
}

scroll_index_map.emplace(texture_name,scroll_index_map.size());
if (scroll_index_map.size() >= MAX_UNIT_TEXTURES) {
Logger::error("Number of textures exceeded max supported by a shader!");
return 0;
}

static const godot::StringName Param_Scroll_texture_diffuse = "scroll_texture_diffuse";
static const godot::StringName Param_Scroll_factor = "scroll_factor";

pushback_shader_array(get_scroll_shader(), Param_Scroll_texture_diffuse, XacLoader::get_model_texture(texture_name));

float scroll_factor = 0.0;
static const godot::StringName tracks = "TexAnim";
static const godot::StringName smoke = "Smoke";
if(texture_name == tracks) { scroll_factor = 2.5; }
else if(texture_name == smoke) { scroll_factor = 0.3; }

pushback_shader_array(get_scroll_shader(), Param_Scroll_factor, scroll_factor);

return scroll_index_map[texture_name];
}
31 changes: 31 additions & 0 deletions extension/src/openvic-extension/singletons/ModelSingleton.hpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
#pragma once

#include <cstdint>
#include <string_view>
#include <godot_cpp/classes/animation.hpp>
#include <godot_cpp/classes/object.hpp>

#include <openvic-simulation/interface/GFXObject.hpp>
#include <openvic-simulation/military/UnitInstanceGroup.hpp>
#include <openvic-simulation/types/OrderedContainers.hpp>
#include "../utility/XSMLoader.hpp"
#include "../utility/XACLoader.hpp"
#include "godot_cpp/classes/shader.hpp"
#include "godot_cpp/classes/shader_material.hpp"
#include "godot_cpp/classes/node3d.hpp"

namespace OpenVic {

struct BuildingInstance;

class ModelSingleton : public godot::Object {
Expand All @@ -31,10 +40,23 @@ namespace OpenVic {

using animation_map_t = deque_ordered_map<GFX::Actor::Animation const*, godot::Dictionary>;
using model_map_t = deque_ordered_map<GFX::Actor const*, godot::Dictionary>;
using xsm_map_t = deque_ordered_map<godot::StringName, godot::Ref<godot::Animation>>;
using xac_map_t = deque_ordered_map<godot::StringName, godot::Node3D*>;
using shader_array_index_map_t = deque_ordered_map<godot::StringName, int32_t>;

animation_map_t animation_cache;
model_map_t model_cache;

xsm_map_t xsm_cache;
xac_map_t xac_cache;

godot::Ref<godot::ShaderMaterial> unit_shader;
godot::Ref<godot::ShaderMaterial> scroll_shader;
shader_array_index_map_t diffuse_texture_index_map;
shader_array_index_map_t specular_texture_index_map;
//shader_array_index_map_t shadow_texture_index_map;
shader_array_index_map_t scroll_index_map;

godot::Dictionary get_animation_dict(GFX::Actor::Animation const& animation);
godot::Dictionary get_model_dict(GFX::Actor const& actor);

Expand All @@ -56,5 +78,14 @@ namespace OpenVic {
godot::Dictionary get_flag_model(bool floating);

godot::TypedArray<godot::Dictionary> get_buildings();

godot::Ref<godot::Animation> get_xsm_animation(godot::String source_file);
godot::Node3D* get_xac_model(godot::String source_file);
godot::Error setup_flag_shader();

godot::Ref<godot::ShaderMaterial> get_unit_shader();
godot::Ref<godot::ShaderMaterial> get_scroll_shader();
int32_t set_unit_material_texture(int32_t type, godot::String name); //MAP_TYPE::Values
int32_t set_scroll_material_texture(godot::String texture_name);
};
}
Loading
Loading