Commit for 2022.06.02 00-03-46.7z
This commit is contained in:
parent
27980e0de9
commit
6418a76456
5
Makefile
5
Makefile
@ -34,8 +34,9 @@ EXT_LIB_NAME += ext
|
||||
#VULKAN_SDK_PATH += /c/VulkanSDK/1.2.162.0/
|
||||
#VULKAN_SDK_PATH += /c/VulkanSDK/1.2.176.1/
|
||||
#VULKAN_SDK_PATH += /c/VulkanSDK/1.2.182.0/
|
||||
VULKAN_SDK_PATH += /c/VulkanSDK/1.2.198.1/
|
||||
#VULKAN_SDK_PATH += /c/VulkanSDK/1.2.198.1/
|
||||
#VULKAN_SDK_PATH += /c/VulkanSDK/1.3.204.1/
|
||||
VULKAN_SDK_PATH += /c/VulkanSDK/1.3.211.0/
|
||||
|
||||
#GLSLC += $(VULKAN_SDK_PATH)/Bin/glslangValidator
|
||||
GLSLC += $(VULKAN_SDK_PATH)/Bin/glslc
|
||||
@ -59,7 +60,7 @@ else ifneq (,$(findstring dreamcast,$(ARCH)))
|
||||
endif
|
||||
ifneq (,$(findstring vulkan,$(REQ_DEPS)))
|
||||
FLAGS += -DVK_USE_PLATFORM_WIN32_KHR -DUF_USE_VULKAN
|
||||
DEPS += -lvulkan -lspirv-cross
|
||||
DEPS += -lvulkan -lspirv-cross #-lVulkanMemoryAllocator
|
||||
INCS += -I$(VULKAN_SDK_PATH)/include
|
||||
LIBS += -L$(VULKAN_SDK_PATH)/Lib
|
||||
endif
|
||||
|
@ -1,12 +1,12 @@
|
||||
{
|
||||
"engine": {
|
||||
"scenes": {
|
||||
"start": "SH2_McDonalds",
|
||||
"start": "SS2",
|
||||
"meshes": { "interleave": true },
|
||||
"matrix": { "reverseInfinite": true },
|
||||
"lights": {
|
||||
"max": 16,
|
||||
"enabled": true
|
||||
"lights": { "enabled": true,
|
||||
"useLightmaps": false,
|
||||
"max": 16
|
||||
},
|
||||
"shadows": {
|
||||
"enabled": true,
|
||||
@ -255,7 +255,7 @@
|
||||
"cursor" : {
|
||||
"visible" : true,
|
||||
"center" : false,
|
||||
"sensitivity": [ 0.5, 0.5 ]
|
||||
"sensitivity": [ 1, 1 ]
|
||||
},
|
||||
"mode" : "windowed", // fullscreen, borderless, windowed
|
||||
"icon" : "./data/textures/icon.png",
|
||||
|
@ -18,12 +18,14 @@
|
||||
"exporter": {
|
||||
"enabled": true,
|
||||
"pretty": false,
|
||||
"compress": true,
|
||||
"encoding": "auto",
|
||||
"compression": "auto",
|
||||
"quantize": false,
|
||||
"precision": 4,
|
||||
"combined": false,
|
||||
"encode buffers": true,
|
||||
"unwrap": true,
|
||||
"quit": true,
|
||||
"mesh": {
|
||||
// "print": true
|
||||
}
|
||||
@ -51,6 +53,7 @@
|
||||
}
|
||||
},
|
||||
// "filter": "NEAREST",
|
||||
"lightmap": true,
|
||||
"flags": {
|
||||
"ATLAS": false,
|
||||
"INVERT": false,
|
||||
|
@ -2,13 +2,13 @@
|
||||
"import": "/model.json",
|
||||
"assets": [
|
||||
// { "filename": "./models/gm_construct.glb" }
|
||||
{ "filename": "./models/gm_construct/graph.json.gz" }
|
||||
{ "filename": "./models/gm_construct/graph.json" }
|
||||
],
|
||||
"metadata": {
|
||||
"model": {
|
||||
"lightmap": true,
|
||||
// "lightmap": false,
|
||||
"baking": {
|
||||
"enabled": false,
|
||||
"enabled": true,
|
||||
"resolution": 1024,
|
||||
"settings": {
|
||||
// "useInputMeshUvs": false
|
||||
|
@ -1,6 +1,7 @@
|
||||
{
|
||||
"import": "/scene.json",
|
||||
"assets": [
|
||||
"./audio/soundscape/ambience.ogg",
|
||||
"./loading.json"
|
||||
],
|
||||
"system": {
|
||||
@ -28,7 +29,7 @@
|
||||
|
||||
"ambient": [ 0.15, 0.15, 0.15 ],
|
||||
|
||||
"fog": {
|
||||
"fog-disabled": {
|
||||
"color": [ 0.5, 0.5, 0.5 ],
|
||||
"range": [ 64, 256 ],
|
||||
"step scale": 2,
|
||||
|
@ -4,16 +4,16 @@
|
||||
// { "filename": "./static.json", "delay": 8 },
|
||||
|
||||
// { "filename": "./models/mcdonalds.glb" }
|
||||
{ "filename": "./models/mcdonalds/graph.json.gz" }
|
||||
{ "filename": "./models/mcdonalds/graph.json" }
|
||||
|
||||
// { "filename": "./models/mini_mcd.glb" }
|
||||
// { "filename": "./models/mini_mcd/graph.json.gz" }
|
||||
// { "filename": "./models/mini_mcd/graph.json" }
|
||||
],
|
||||
"metadata": {
|
||||
"model": {
|
||||
"lightmap": true,
|
||||
// "lightmap": false,
|
||||
"baking": {
|
||||
"enabled": false,
|
||||
"enabled": true,
|
||||
"resolution": 2048,
|
||||
"settings": {
|
||||
"useInputMeshUvs": false
|
||||
@ -23,7 +23,7 @@
|
||||
"tags": {
|
||||
"/^worldspawn/": {
|
||||
"physics": { "type": "mesh", "static": true },
|
||||
"grid": { "size": [3,2,3], "epsilon": 1.0, "cleanup": true, "print": true }
|
||||
"grid": { "size": [4,1,4], "epsilon": 1.0, "cleanup": true, "print": true }
|
||||
},
|
||||
"info_player_spawn": { "action": "attach", "filename": "./player.json", "preserve orientation": true },
|
||||
|
||||
|
@ -10,9 +10,9 @@
|
||||
"model": {
|
||||
"cull mode": "none",
|
||||
"alpha mode": "BLEND",
|
||||
"lightmap": true,
|
||||
// "lightmap": false,
|
||||
"baking": {
|
||||
"enabled": false,
|
||||
"enabled": true,
|
||||
"resolution": 1024,
|
||||
"settings": {
|
||||
"useInputMeshUvs": false
|
||||
|
@ -3,26 +3,21 @@
|
||||
"assets": [
|
||||
// { "filename": "./craeture.json", "delay": 1 },
|
||||
|
||||
// { "filename": "./models/tiny_msci.glb", "delay": 0, "single threaded": false, "category": "models" }
|
||||
// { "filename": "./models/tiny_msci/graph.json", "delay": 0, "single threaded": false, "category": "models" }
|
||||
// { "filename": "./models/tiny_msci/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
|
||||
// { "filename": "./models/tiny_msci.glb" }
|
||||
// { "filename": "./models/tiny_msci/graph.json" }
|
||||
|
||||
// { "filename": "./models/micro_sci.glb", "delay": 0, "single threaded": false, "category": "models" }
|
||||
// { "filename": "./models/micro_sci/graph.json", "delay": 0, "single threaded": false, "category": "models" }
|
||||
{ "filename": "./models/micro_sci/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
|
||||
// { "filename": "./models/micro_sci.glb" }
|
||||
// { "filename": "./models/micro_sci/graph.json" }
|
||||
|
||||
// { "filename": "./models/msci.glb" }
|
||||
// { "filename": "./models/msci/graph.json" }
|
||||
|
||||
// { "filename": "./models/msci.glb", "delay": 0, "single threaded": false, "category": "models" }
|
||||
// { "filename": "./models/msci/graph.json", "delay": 0, "single threaded": false, "category": "models" }
|
||||
// { "filename": "./models/msci/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
|
||||
|
||||
// { "filename": "./models/medsci.glb", "delay": 0, "single threaded": false }
|
||||
// { "filename": "./models/medsci/graph.json", "delay": 0, "single threaded": false, "category": "models" }
|
||||
// { "filename": "./models/medsci/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
|
||||
// { "filename": "./models/medsci.glb" }
|
||||
{ "filename": "./models/medsci/graph.json" }
|
||||
],
|
||||
"metadata": {
|
||||
"model": {
|
||||
"lightmap": true,
|
||||
// "lightmap": false,
|
||||
"baking": {
|
||||
"enabled": true,
|
||||
"resolution": 1024
|
||||
@ -31,7 +26,7 @@
|
||||
"tags": {
|
||||
"/^worldspawn/": {
|
||||
"physics": { "type": "mesh", "static": true },
|
||||
"grid": { "size": [5,2,5], "epsilon": 1.0, "cleanup": true, "print": true }
|
||||
"grid": { "size": [5,1,5], "epsilon": 1.0, "cleanup": true, "print": true }
|
||||
},
|
||||
"info_player_spawn": {
|
||||
"action": "attach",
|
||||
|
@ -15,7 +15,7 @@ float gaSchlickGGX(float cosLi, float cosLo, float roughness) {
|
||||
vec3 fresnelSchlick(vec3 F0, float cosTheta) { return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); }
|
||||
#if !BAKING && !COMPUTE
|
||||
void pbr() {
|
||||
if ( validTextureIndex( surface.instance.lightmapID ) ) return;
|
||||
if ( bool(ubo.useLightmaps) && validTextureIndex( surface.instance.lightmapID ) ) return;
|
||||
|
||||
const float Rs = 4.0; // specular lighting looks gross without this
|
||||
const vec3 F0 = mix(vec3(0.04), surface.material.albedo.rgb, surface.material.metallic);
|
||||
|
@ -62,7 +62,7 @@ layout (binding = 5) uniform UBO {
|
||||
uint shadowSamples;
|
||||
|
||||
uint indexSkybox;
|
||||
uint padding1;
|
||||
uint useLightmaps;
|
||||
uint padding2;
|
||||
uint padding3;
|
||||
} ubo;
|
||||
@ -235,7 +235,7 @@ void populateSurface() {
|
||||
|
||||
}
|
||||
// Lightmap
|
||||
if ( validTextureIndex( surface.instance.lightmapID ) ) {
|
||||
if ( bool(ubo.useLightmaps) && validTextureIndex( surface.instance.lightmapID ) ) {
|
||||
surface.light += surface.material.albedo * sampleTexture( surface.instance.lightmapID, surface.st );
|
||||
}
|
||||
// Emissive textures
|
||||
|
@ -25,6 +25,7 @@ namespace {
|
||||
#if UF_ENV_DREAMCAST
|
||||
arch_stk_trace(1);
|
||||
#endif
|
||||
if ( client::terminated ) return;
|
||||
UF_MSG_INFO("Termination via std::atexit()!");
|
||||
ext::ready = false;
|
||||
client::ready = false;
|
||||
@ -125,6 +126,7 @@ int main(int argc, char** argv){
|
||||
#endif
|
||||
}
|
||||
if ( !client::terminated ) {
|
||||
client::terminated = true;
|
||||
UF_MSG_INFO("Natural termination!");
|
||||
ext::terminate();
|
||||
client::terminate();
|
||||
|
@ -20,12 +20,19 @@
|
||||
|
||||
namespace ext {
|
||||
namespace json {
|
||||
extern uf::stl::string PREFERRED_COMPRESSION;
|
||||
extern uf::stl::string PREFERRED_ENCODING;
|
||||
|
||||
struct UF_API EncodingSettings {
|
||||
uf::stl::string compression = ""; // auto-assume compression scheme
|
||||
uf::stl::string encoding = ""; // auto-assume re-encoding scheme
|
||||
bool pretty = false;
|
||||
bool compress = false;
|
||||
bool quantize = false;
|
||||
uint8_t precision = 0;
|
||||
};
|
||||
struct UF_API DecodingSettings {
|
||||
uf::stl::string encoding = "";
|
||||
};
|
||||
|
||||
// cares not about breaking
|
||||
void UF_API forEach( ext::json::Value& json, const std::function<void(ext::json::Value&)>& function );
|
||||
@ -50,7 +57,8 @@ namespace ext {
|
||||
|
||||
uf::stl::string UF_API encode( const ext::json::Value& json, bool pretty = true );
|
||||
uf::stl::string UF_API encode( const ext::json::Value& json, const ext::json::EncodingSettings& settings );
|
||||
ext::json::Value& UF_API decode( ext::json::Value& json, const uf::stl::string& str );
|
||||
|
||||
ext::json::Value& UF_API decode( ext::json::Value& json, const uf::stl::string& str, const DecodingSettings& = {} );
|
||||
#if UF_USE_LUA
|
||||
uf::stl::string UF_API encode( const sol::table& table );
|
||||
#endif
|
||||
|
@ -94,6 +94,7 @@ template<> inline bool ext::json::Value::is<uint64_t>(bool strict) const { retur
|
||||
template<> inline bool ext::json::Value::is<float>(bool strict) const { return strict ? is_number_float() : is_number(); }
|
||||
template<> inline bool ext::json::Value::is<double>(bool strict) const { return strict ? is_number_float() : is_number(); }
|
||||
template<> inline bool ext::json::Value::is<uf::stl::string>(bool strict) const { return is_string(); }
|
||||
// template<> inline bool ext::json::Value::is<std::string>(bool strict) const { return is_string(); }
|
||||
|
||||
#if UF_ENV_DREAMCAST
|
||||
template<> inline bool ext::json::Value::is<int>(bool strict) const { return strict ? is_number_integer() : is_number(); }
|
||||
|
@ -54,8 +54,10 @@
|
||||
#define UF_MSG_ERROR(X) UF_MSG(X, " ERROR ");
|
||||
|
||||
#if UF_NO_EXCEPTIONS
|
||||
#define UF_EXCEPTIONS 0
|
||||
#define UF_EXCEPTION(X) { UF_MSG_ERROR(X); std::abort(); }
|
||||
#else
|
||||
#define UF_NO_EXCEPTIONS 0
|
||||
#define UF_EXCEPTION(X) {\
|
||||
uf::stl::stringstream str;\
|
||||
str << X;\
|
||||
|
@ -50,6 +50,7 @@ namespace uf {
|
||||
public:
|
||||
bool exists( const name_t& name );
|
||||
void removeHook( const name_t& name, size_t uid );
|
||||
void removeHooks();
|
||||
|
||||
size_t addHook( const name_t& name, const pod::Hook::function_t& callback, const pod::Hook::Type& = {UF_USERDATA_CTTI(void), 0} );
|
||||
size_t addHook( const name_t& name, const std::function<void()>& callback );
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
namespace uf {
|
||||
class UF_API Serializer : public ext::json::Document {
|
||||
protected:
|
||||
uf::stl::string m_filename = "";
|
||||
public:
|
||||
typedef uf::stl::string output_t;
|
||||
typedef uf::stl::string input_t;
|
||||
@ -24,7 +26,7 @@ namespace uf {
|
||||
|
||||
Serializer::output_t serialize( bool pretty = false ) const;
|
||||
Serializer::output_t serialize( const ext::json::EncodingSettings& ) const;
|
||||
void deserialize( const uf::stl::string& );
|
||||
void deserialize( const uf::stl::string&, const ext::json::DecodingSettings& = {} );
|
||||
|
||||
// serializeable
|
||||
template<typename T>
|
||||
@ -60,6 +62,7 @@ namespace uf {
|
||||
return res;
|
||||
}
|
||||
|
||||
static uf::stl::string resolveFilename( const uf::stl::string& filename, bool compareTimes = true );
|
||||
bool readFromFile( const uf::stl::string& from, const uf::stl::string& hash = "" );
|
||||
bool writeToFile( const uf::stl::string& to, const ext::json::EncodingSettings& = {} ) const;
|
||||
|
||||
|
@ -11,7 +11,10 @@ namespace uf {
|
||||
namespace string {
|
||||
// bool match( const uf::stl::string& str, const uf::stl::string& r );
|
||||
bool UF_API isRegex( const uf::stl::string& str );
|
||||
uf::stl::vector<uf::stl::string> UF_API matches( const uf::stl::string& str, const uf::stl::string& r );
|
||||
uf::stl::vector<uf::stl::string> UF_API match( const uf::stl::string& str, const uf::stl::string& r );
|
||||
inline uf::stl::vector<uf::stl::string> UF_API matches( const uf::stl::string& str, const uf::stl::string& r ) { return uf::string::match( str, r ); }
|
||||
|
||||
bool UF_API matched( const uf::stl::string& str, const uf::stl::string& r );
|
||||
|
||||
uf::stl::string UF_API replace( const uf::stl::string&, const uf::stl::string&, const uf::stl::string& );
|
||||
uf::stl::string UF_API lowercase( const uf::stl::string& );
|
||||
|
@ -181,7 +181,7 @@ void uf::Asset::load( const uf::stl::string& callback, const uf::Asset::Payload&
|
||||
|
||||
uf::Asset::Payload uf::Asset::resolveToPayload( const uf::stl::string& uri, const uf::stl::string& mime ) {
|
||||
uf::stl::string extension = uf::string::lowercase( uf::io::extension( uri, -1 ) );
|
||||
uf::stl::string basename = uf::string::lowercase( uf::string::replace( uf::io::filename( uri ), ".gz", "" ) );
|
||||
uf::stl::string basename = uf::string::lowercase( uf::string::replace( uf::io::filename( uri ), "/.(?:gz|lz)$/", "" ) );
|
||||
uf::Asset::Payload payload;
|
||||
|
||||
static uf::stl::unordered_map<uf::stl::string,uf::Asset::Type> typemap = {
|
||||
@ -192,6 +192,8 @@ uf::Asset::Payload uf::Asset::resolveToPayload( const uf::stl::string& uri, cons
|
||||
{ "ogg", uf::Asset::Type::AUDIO },
|
||||
|
||||
{ "json", uf::Asset::Type::JSON },
|
||||
{ "bson", uf::Asset::Type::JSON },
|
||||
{ "cbor", uf::Asset::Type::JSON },
|
||||
|
||||
{ "lua", uf::Asset::Type::LUA },
|
||||
|
||||
@ -207,6 +209,8 @@ uf::Asset::Payload uf::Asset::resolveToPayload( const uf::stl::string& uri, cons
|
||||
|
||||
if ( typemap.count( extension ) == 1 ) payload.type = typemap[extension];
|
||||
if ( basename == "graph.json" ) payload.type = uf::Asset::Type::GRAPH;
|
||||
if ( basename == "graph.bson" ) payload.type = uf::Asset::Type::GRAPH;
|
||||
if ( basename == "graph.cbor" ) payload.type = uf::Asset::Type::GRAPH;
|
||||
|
||||
return payload;
|
||||
}
|
||||
@ -232,6 +236,12 @@ uf::stl::string uf::Asset::cache( const uf::Asset::Payload& payload ) {
|
||||
return "";
|
||||
}
|
||||
filename = cached;
|
||||
} else {
|
||||
// do implicit loading of json files (could be encoded as bson, cbor, and compressed as gz, lz)
|
||||
if ( extension == "json" ) {
|
||||
filename = uf::Serializer::resolveFilename( filename );
|
||||
extension = uf::io::extension( extension );
|
||||
}
|
||||
}
|
||||
if ( !uf::io::exists( filename ) ) {
|
||||
if ( !uf::Asset::assertionLoad ) {
|
||||
@ -255,7 +265,7 @@ uf::stl::string uf::Asset::cache( const uf::Asset::Payload& payload ) {
|
||||
uf::stl::string uf::Asset::load(const uf::Asset::Payload& payload ) {
|
||||
uf::stl::string filename = payload.filename;
|
||||
uf::stl::string extension = uf::string::lowercase(uf::io::extension( payload.filename, -1 ));
|
||||
uf::stl::string basename = uf::string::replace( uf::io::filename( payload.filename ), ".gz", "" );
|
||||
uf::stl::string basename = uf::string::lowercase( uf::string::replace( uf::io::filename( payload.filename ), "/.(?:gz|lz)$/", "" ) );
|
||||
if ( payload.filename.substr(0,5) == "https" ) {
|
||||
uf::stl::string hash = uf::string::sha256( payload.filename );
|
||||
uf::stl::string cached = uf::io::root + "/cache/http/" + hash + "." + extension;
|
||||
@ -268,6 +278,12 @@ uf::stl::string uf::Asset::load(const uf::Asset::Payload& payload ) {
|
||||
return "";
|
||||
}
|
||||
filename = cached;
|
||||
} else {
|
||||
// do implicit loading of json files (could be encoded as bson, cbor, and compressed as gz, lz)
|
||||
if ( extension == "json" ) {
|
||||
filename = uf::Serializer::resolveFilename( filename );
|
||||
extension = uf::io::extension( extension );
|
||||
}
|
||||
}
|
||||
if ( !uf::io::exists( filename ) ) {
|
||||
if ( !uf::Asset::assertionLoad ) {
|
||||
|
@ -112,6 +112,12 @@ void uf::Behaviors::destroy() {
|
||||
uf::Object& self = *((uf::Object*) this);
|
||||
if ( !self.isValid() ) return;
|
||||
UF_BEHAVIOR_POLYFILL(destroy)
|
||||
m_behaviors.clear();
|
||||
m_graph.initialize.clear();
|
||||
m_graph.tick.clear();
|
||||
m_graph.tickMT.clear();
|
||||
m_graph.render.clear();
|
||||
m_graph.destroy.clear();
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -197,7 +197,7 @@ namespace {
|
||||
|
||||
ext::json::reserve( json["buffers"], mesh.buffers.size() );
|
||||
for ( auto i = 0; i < mesh.buffers.size(); ++i ) {
|
||||
const uf::stl::string filename = settings.filename + ".buffer." + std::to_string(i) + "." + ( settings.compress ? "gz" : "bin" );
|
||||
const uf::stl::string filename = settings.filename + ".buffer." + std::to_string(i) + "." + ( settings.compression != "" ? settings.compression : "bin" );
|
||||
uf::io::write( filename, mesh.buffers[i] );
|
||||
json["buffers"].emplace_back(uf::io::filename( filename ));
|
||||
}
|
||||
@ -224,10 +224,11 @@ void uf::graph::save( const pod::Graph& graph, const uf::stl::string& filename )
|
||||
uf::Serializer serializer;
|
||||
uf::Serializer metadata;
|
||||
|
||||
const ::EncodingSettings settings = ::EncodingSettings{
|
||||
::EncodingSettings settings = ::EncodingSettings{
|
||||
{
|
||||
/*.compression = */graph.metadata["exporter"]["compression"].as<uf::stl::string>("auto"),
|
||||
/*.encoding = */graph.metadata["exporter"]["encoding"].as<uf::stl::string>("auto"),
|
||||
/*.pretty = */graph.metadata["exporter"]["pretty"].as<bool>(),
|
||||
/*.compress = */graph.metadata["exporter"]["compress"].as<bool>(),
|
||||
/*.quantize = */graph.metadata["exporter"]["quantize"].as<bool>(),
|
||||
/*.precision = */graph.metadata["exporter"]["precision"].as<uint8_t>(),
|
||||
},
|
||||
@ -236,6 +237,10 @@ void uf::graph::save( const pod::Graph& graph, const uf::stl::string& filename )
|
||||
/*.unwrap = */graph.metadata["exporter"]["unwrap"].as<bool>(true),
|
||||
/*.filename = */directory + "/graph.json",
|
||||
};
|
||||
|
||||
if ( settings.encoding == "auto" ) settings.encoding = ext::json::PREFERRED_ENCODING;
|
||||
if ( settings.compression == "auto" ) settings.compression = ext::json::PREFERRED_COMPRESSION;
|
||||
|
||||
if ( !settings.combined ) uf::io::mkdir(directory);
|
||||
#if UF_USE_XATLAS
|
||||
/*
|
||||
@ -297,7 +302,8 @@ void uf::graph::save( const pod::Graph& graph, const uf::stl::string& filename )
|
||||
encode(mesh, s).writeToFile(s.filename, settings);
|
||||
uf::Serializer json;
|
||||
json["name"] = name;
|
||||
json["filename"] = uf::io::filename(s.filename + (settings.compress ? ".gz" : ""));
|
||||
// json["filename"] = uf::io::filename(s.filename + (settings.compress ? ".gz" : ""));
|
||||
json["filename"] = uf::io::filename(s.filename);
|
||||
serializer["meshes"].emplace_back( json );
|
||||
} else {
|
||||
s.filename = directory+"/mesh."+std::to_string(i);
|
||||
@ -403,7 +409,8 @@ void uf::graph::save( const pod::Graph& graph, const uf::stl::string& filename )
|
||||
uf::stl::string f = "animation."+std::to_string(i)+".json";
|
||||
auto& animation = /*graph.storage*/uf::graph::storage.animations.map.at(name);
|
||||
encode(animation, settings).writeToFile(directory+"/"+f, settings);
|
||||
serializer["animations"].emplace_back(f + (settings.compress ? ".gz" : ""));
|
||||
// serializer["animations"].emplace_back(f + (settings.compress ? ".gz" : ""));
|
||||
serializer["animations"].emplace_back(f);
|
||||
}
|
||||
} else {
|
||||
for ( auto& name : graph.animations ) {
|
||||
@ -435,6 +442,12 @@ void uf::graph::save( const pod::Graph& graph, const uf::stl::string& filename )
|
||||
if ( !settings.combined ) target = directory + "/graph.json";
|
||||
serializer.writeToFile( target, settings );
|
||||
UF_MSG_DEBUG("Saving graph to `" << target << "`");
|
||||
|
||||
if ( graph.metadata["exporter"]["quit"].as<bool>(true) ) {
|
||||
ext::json::Value payload;
|
||||
payload["message"] = "Termination after gltf conversion requested.";
|
||||
uf::scene::getCurrentScene().queueHook("system:Quit", payload);
|
||||
}
|
||||
}
|
||||
|
||||
uf::stl::string uf::graph::print( const pod::Graph& graph ) {
|
||||
|
@ -693,7 +693,7 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
|
||||
*/
|
||||
ext::json::forEach( graph.metadata["tags"], [&]( const uf::stl::string& key, ext::json::Value& value ) {
|
||||
if ( uf::string::isRegex( key ) ) {
|
||||
if ( uf::string::matches( node.name, key ).empty() ) return;
|
||||
if ( !uf::string::matched( node.name, key ) ) return;
|
||||
} else if ( node.name != key ) return;
|
||||
tag = value;
|
||||
});
|
||||
|
@ -28,7 +28,9 @@ UF_API bool ext::freetype::initialized() {
|
||||
return ext::freetype::library.loaded;
|
||||
}
|
||||
UF_API void ext::freetype::terminate() {
|
||||
if ( !ext::freetype::library.loaded ) return;
|
||||
FT_Done_FreeType(ext::freetype::library.library);
|
||||
ext::freetype::library.loaded = false;
|
||||
}
|
||||
|
||||
UF_API ext::freetype::Glyph ext::freetype::initialize( const uf::stl::string& font ) {
|
||||
|
@ -265,7 +265,7 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
|
||||
if ( !ext::json::isObject( value["grid"] ) ) return; // no tag["grid"] defined
|
||||
if ( ext::json::isNull( value["grid"]["size"] ) ) return; // no tag["grid"]["size"] defined
|
||||
if ( uf::string::isRegex( key ) ) {
|
||||
if ( uf::string::matches( m.name, key ).empty() ) return;
|
||||
if ( !uf::string::matched( m.name, key ) ) return;
|
||||
} else if ( m.name != key ) return;
|
||||
meshgrid.metadata = value["grid"];
|
||||
});
|
||||
|
@ -111,7 +111,7 @@ void ext::json::forEach( const ext::json::Value& json, const std::function<void(
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(UF_JSON_USE_NLOHMANN) && UF_JSON_USE_NLOHMANN
|
||||
#if UF_JSON_USE_NLOHMANN
|
||||
uf::stl::vector<uf::stl::string> ext::json::keys( const ext::json::Value& v ) {
|
||||
uf::stl::vector<uf::stl::string> keys;
|
||||
if ( !ext::json::isObject( v ) ) return keys;
|
||||
@ -120,7 +120,7 @@ uf::stl::vector<uf::stl::string> ext::json::keys( const ext::json::Value& v ) {
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
#elif defined(UF_JSON_USE_RAPIDJSON) && UF_JSON_USE_RAPIDJSON
|
||||
#elif UF_JSON_USE_RAPIDJSON
|
||||
rapidjson::Document::AllocatorType ext::json::allocator;
|
||||
#endif
|
||||
|
||||
@ -150,20 +150,33 @@ ext::json::Value& ext::json::reencode( ext::json::Value& x, const EncodingSettin
|
||||
return x;
|
||||
}
|
||||
|
||||
uf::stl::string ext::json::PREFERRED_COMPRESSION = "gz";
|
||||
uf::stl::string ext::json::PREFERRED_ENCODING = "bson";
|
||||
|
||||
uf::stl::string ext::json::encode( const ext::json::Value& json, bool pretty ) {
|
||||
return ext::json::encode( json, ext::json::EncodingSettings{ .pretty = true } );
|
||||
}
|
||||
uf::stl::string ext::json::encode( const ext::json::Value& _json, const ext::json::EncodingSettings& settings ) {
|
||||
ext::json::Value json = ext::json::reencode( _json, settings );
|
||||
#if defined(UF_JSON_USE_NLOHMANN) && UF_JSON_USE_NLOHMANN
|
||||
return settings.pretty ? json.dump(1, '\t') : json.dump();
|
||||
#elif defined(UF_JSON_USE_JSONCPP) && UF_JSON_USE_JSONCPP
|
||||
Json::FastWriter fast;
|
||||
Json::StyledWriter styled;
|
||||
uf::stl::string output = settings.pretty ? styled.write(json) : fast.write(json);
|
||||
if ( output.back() == '\n' ) output.pop_back();
|
||||
return output;
|
||||
#elif defined(UF_JSON_USE_LUA) && UF_JSON_USE_LUA
|
||||
#if UF_JSON_USE_NLOHMANN
|
||||
// emit raw json
|
||||
if ( settings.encoding == "" || settings.encoding == "json" ) {
|
||||
return settings.pretty ? json.dump(1, '\t') : json.dump();
|
||||
}
|
||||
// emit bson
|
||||
if ( settings.encoding == "bson" ) {
|
||||
auto buffer = nlohmann::json::to_bson( static_cast<ext::json::base_value>(json) );
|
||||
return uf::stl::string( buffer.begin(), buffer.end() );
|
||||
}
|
||||
// emit cbor
|
||||
if ( settings.encoding == "cbor" ) {
|
||||
auto buffer = nlohmann::json::to_cbor( static_cast<ext::json::base_value>(json) );
|
||||
return uf::stl::string( buffer.begin(), buffer.end() );
|
||||
}
|
||||
// should probably default to json, not my problem
|
||||
UF_MSG_ERROR("invalid encoding requested: " << settings.encoding);
|
||||
return "";
|
||||
#elif UF_JSON_USE_LUA
|
||||
return ext::lua::state["json"]["encode"]( _json );
|
||||
#endif
|
||||
}
|
||||
@ -173,23 +186,24 @@ uf::stl::string ext::json::encode( const sol::table& table ) {
|
||||
return ext::lua::state["json"]["encode"]( table );
|
||||
}
|
||||
#endif
|
||||
ext::json::Value& ext::json::decode( ext::json::Value& json, const uf::stl::string& str ) {
|
||||
#if defined(UF_JSON_USE_NLOHMANN) && UF_JSON_USE_NLOHMANN
|
||||
#if UF_NO_EXCEPTIONS
|
||||
json = nlohmann::json::parse(str, nullptr, true, true);
|
||||
#else
|
||||
ext::json::Value& ext::json::decode( ext::json::Value& json, const uf::stl::string& str, const DecodingSettings& settings ) {
|
||||
#if UF_JSON_USE_NLOHMANN
|
||||
#if !UF_NO_EXCEPTIONS
|
||||
bool exceptions = true;
|
||||
try {
|
||||
json = nlohmann::json::parse(str, nullptr, true, true);
|
||||
#endif
|
||||
if ( settings.encoding == "" || settings.encoding == "json" )
|
||||
json = nlohmann::json::parse(str, nullptr, exceptions, true);
|
||||
else if ( settings.encoding == "bson" )
|
||||
json = nlohmann::json::from_bson(str, exceptions, true);
|
||||
else if ( settings.encoding == "cbor" )
|
||||
json = nlohmann::json::from_cbor(str, exceptions, true);
|
||||
#if !UF_NO_EXCEPTIONS
|
||||
} catch ( nlohmann::json::parse_error& e ) {
|
||||
UF_MSG_ERROR("JSON error: " << e.what() << "\tAttempted to parse: " << str)
|
||||
}
|
||||
#endif
|
||||
#elif defined(UF_JSON_USE_JSONCPP) && UF_JSON_USE_JSONCPP
|
||||
Json::Reader reader;
|
||||
if ( !reader.parse(str, json) ) {
|
||||
UF_MSG_ERROR("JSON error: " << reader.getFormattedErrorMessages() << "\tAttempted to parse: " << str)
|
||||
}
|
||||
#elif defined(UF_JSON_USE_LUA) && UF_JSON_USE_LUA
|
||||
#elif UF_JSON_USE_LUA
|
||||
json = ext::lua::state["json"]["decode"]( str );
|
||||
#endif
|
||||
return json;
|
||||
|
@ -233,6 +233,7 @@ void ext::reactphysics::tick( float delta ) {
|
||||
ext::reactphysics::syncFrom( accumulator / ext::reactphysics::timescale );
|
||||
}
|
||||
void ext::reactphysics::terminate() {
|
||||
if ( !::world ) return;
|
||||
::common.destroyPhysicsWorld(::world);
|
||||
::world = NULL;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#if UF_USE_VULKAN
|
||||
|
||||
#define VMA_VULKAN_VERSION 1002000
|
||||
#define VMA_IMPLEMENTATION
|
||||
|
||||
#include <uf/ext/vulkan/buffer.h>
|
||||
|
@ -552,10 +552,10 @@ void ext::vulkan::Device::initialize() {
|
||||
VkApplicationInfo appInfo = {};
|
||||
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||
appInfo.pApplicationName = "Program";
|
||||
appInfo.applicationVersion = VK_MAKE_VERSION(1, 2, 0);
|
||||
appInfo.applicationVersion = VK_MAKE_VERSION(1, 3, 0);
|
||||
appInfo.pEngineName = "Engine";
|
||||
appInfo.engineVersion = VK_MAKE_VERSION(1, 2, 0);
|
||||
appInfo.apiVersion = VK_API_VERSION_1_2;
|
||||
appInfo.engineVersion = VK_MAKE_VERSION(1, 3, 0);
|
||||
appInfo.apiVersion = VK_API_VERSION_1_3;
|
||||
|
||||
VkInstanceCreateInfo createInfo = {};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
@ -937,7 +937,7 @@ void ext::vulkan::Device::initialize() {
|
||||
{
|
||||
/*
|
||||
VmaAllocatorCreateInfo allocatorInfo = {};
|
||||
allocatorInfo.vulkanApiVersion = VK_API_VERSION_1_2;
|
||||
allocatorInfo.vulkanApiVersion = VK_API_VERSION_1_3;
|
||||
allocatorInfo.physicalDevice = physicalDevice;
|
||||
allocatorInfo.instance = instance;
|
||||
allocatorInfo.device = logicalDevice;
|
||||
@ -950,7 +950,7 @@ void ext::vulkan::Device::initialize() {
|
||||
vulkanFunctions.vkGetDeviceProcAddr = &vkGetDeviceProcAddr;
|
||||
|
||||
VmaAllocatorCreateInfo allocatorInfo = {};
|
||||
allocatorInfo.vulkanApiVersion = VK_API_VERSION_1_2;
|
||||
allocatorInfo.vulkanApiVersion = VK_API_VERSION_1_3;
|
||||
allocatorInfo.physicalDevice = physicalDevice;
|
||||
allocatorInfo.instance = instance;
|
||||
allocatorInfo.device = logicalDevice;
|
||||
|
@ -141,7 +141,7 @@ bool ext::vulkan::Texture::generated() const {
|
||||
return view != VK_NULL_HANDLE;
|
||||
}
|
||||
void ext::vulkan::Texture::destroy() {
|
||||
if ( !device ) return;
|
||||
if ( !device || !device->logicalDevice ) return; // device->logicalDevice should never be null, but it happens, somehow
|
||||
|
||||
if ( view != VK_NULL_HANDLE ) {
|
||||
vkDestroyImageView(device->logicalDevice, view, nullptr);
|
||||
|
@ -384,7 +384,7 @@ void ext::vulkan::destroy() {
|
||||
*/
|
||||
|
||||
for ( auto& renderMode : renderModes ) {
|
||||
if ( !renderMode ) continue;
|
||||
if ( !renderMode || !renderMode->device ) continue;
|
||||
renderMode->destroy();
|
||||
// delete renderMode;
|
||||
renderMode = NULL;
|
||||
|
@ -21,6 +21,9 @@ void uf::Hooks::removeHook( const uf::Hooks::name_t& name, size_t uid ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
void uf::Hooks::removeHooks() {
|
||||
this->m_container.clear();
|
||||
}
|
||||
/*
|
||||
uf::Hooks::return_t uf::Hooks::call( const uf::Hooks::name_t& name ) {
|
||||
pod::Hook::userdata_t payload{};
|
||||
|
@ -77,14 +77,14 @@ uf::stl::string UF_API uf::io::sanitize( const uf::stl::string& str, const uf::s
|
||||
// flatten all "/./"
|
||||
{
|
||||
uf::stl::string tmp;
|
||||
while ( path != (tmp = uf::string::replace(path, "/./", "/")) ) {
|
||||
while ( path != (tmp = uf::string::replace(path, "/\\/\\.\\//", "/")) ) {
|
||||
path = tmp;
|
||||
}
|
||||
}
|
||||
// flatten all "//"
|
||||
{
|
||||
uf::stl::string tmp;
|
||||
while ( path != (tmp = uf::string::replace(path, "//", "/")) ) {
|
||||
while ( path != (tmp = uf::string::replace(path, "/\\/\\//", "/")) ) {
|
||||
path = tmp;
|
||||
}
|
||||
}
|
||||
@ -151,10 +151,16 @@ size_t UF_API uf::io::write( const uf::stl::string& filename, const void* buffer
|
||||
|
||||
// indirection for different compression formats, currently only using zlib's gzFile shit
|
||||
uf::stl::vector<uint8_t> UF_API uf::io::decompress( const uf::stl::string& filename ) {
|
||||
return ext::zlib::decompressFromFile( filename );
|
||||
uf::stl::string extension = uf::io::extension( filename );
|
||||
if ( extension == "gz" ) return ext::zlib::decompressFromFile( filename );
|
||||
UF_MSG_ERROR("unsupported compression format requested: " << extension);
|
||||
return {};
|
||||
}
|
||||
size_t UF_API uf::io::compress( const uf::stl::string& filename, const void* buffer, size_t size ) {
|
||||
return ext::zlib::compressToFile( filename, buffer, size );
|
||||
uf::stl::string extension = uf::io::extension( filename );
|
||||
if ( extension == "gz" ) return ext::zlib::compressToFile( filename, buffer, size );
|
||||
UF_MSG_ERROR("unsupported compression format requested: " << extension);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uf::stl::string UF_API uf::io::hash( const uf::stl::string& filename ) {
|
||||
|
@ -159,7 +159,9 @@ char UF_API_CALL uf::IoStream::readChar(const bool& loop) {
|
||||
if ( !ext::ncurses.initialized() ) this->initialize();
|
||||
#endif
|
||||
if ( !uf::IoStream::ncurses ) {
|
||||
return std::cin.get();
|
||||
auto ch = std::cin.get();
|
||||
::info.input.history.push_back( std::to_string(ch) );
|
||||
return ch;
|
||||
}
|
||||
#if UF_USE_NCURSES
|
||||
while ( loop ) {
|
||||
@ -167,8 +169,8 @@ char UF_API_CALL uf::IoStream::readChar(const bool& loop) {
|
||||
if ( ::info.character == ERR ) continue;
|
||||
if ( ::info.character > 0 && ::info.character < 128 ) return ::info.character;
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
uf::stl::string UF_API_CALL uf::IoStream::readString(const bool& loop) {
|
||||
#if UF_USE_NCURSES
|
||||
@ -178,6 +180,7 @@ uf::stl::string UF_API_CALL uf::IoStream::readString(const bool& loop) {
|
||||
if ( !uf::IoStream::ncurses ) {
|
||||
uf::stl::string in;
|
||||
std::getline(std::cin, in);
|
||||
::info.input.history.push_back( in );
|
||||
return in;
|
||||
}
|
||||
#if UF_USE_NCURSES
|
||||
@ -259,8 +262,8 @@ uf::stl::string UF_API_CALL uf::IoStream::readString(const bool& loop) {
|
||||
}
|
||||
uf::iostream << "\n";
|
||||
::info.input.history.push_back(::info.input.buffer);
|
||||
return ::info.input.buffer;
|
||||
#endif
|
||||
return ::info.input.buffer;
|
||||
}
|
||||
uf::String UF_API_CALL uf::IoStream::readUString(const bool& loop) {
|
||||
#if UF_USE_NCURSES
|
||||
@ -270,6 +273,7 @@ uf::String UF_API_CALL uf::IoStream::readUString(const bool& loop) {
|
||||
if ( !uf::IoStream::ncurses ) {
|
||||
uf::stl::string in;
|
||||
std::getline(std::cin, in);
|
||||
::info.input.history.push_back( in );
|
||||
return in;
|
||||
}
|
||||
#if UF_USE_NCURSES
|
||||
@ -377,8 +381,8 @@ uf::String UF_API_CALL uf::IoStream::readUString(const bool& loop) {
|
||||
}
|
||||
uf::iostream << "\n";
|
||||
::info.input.history.push_back(::info.input.buffer);
|
||||
return ::info.input.buffer;
|
||||
#endif
|
||||
return ::info.input.buffer;
|
||||
}
|
||||
char UF_API_CALL uf::IoStream::writeChar( char ch ) {
|
||||
#if UF_USE_NCURSES
|
||||
@ -398,13 +402,14 @@ char UF_API_CALL uf::IoStream::writeChar( char ch ) {
|
||||
if ( !uf::IoStream::ncurses ) {
|
||||
if ( ch == '\n' ) std::cout << std::endl;
|
||||
else std::cout << ch;
|
||||
::info.input.history.push_back( std::to_string(ch) );
|
||||
return ch;
|
||||
}
|
||||
#if UF_USE_NCURSES
|
||||
ext::ncurses.addChar(ch);
|
||||
ext::ncurses.refresh();
|
||||
return ch;
|
||||
#endif
|
||||
return ch;
|
||||
}
|
||||
const uf::stl::string& UF_API_CALL uf::IoStream::writeString( const uf::stl::string& str ) {
|
||||
#if UF_USE_NCURSES
|
||||
@ -425,13 +430,14 @@ const uf::stl::string& UF_API_CALL uf::IoStream::writeString( const uf::stl::str
|
||||
if ( !uf::IoStream::ncurses ) {
|
||||
if ( str == "\n" ) std::cout << std::endl;
|
||||
else std::cout << str;
|
||||
::info.input.history.push_back( str );
|
||||
return str;
|
||||
}
|
||||
#if UF_USE_NCURSES
|
||||
ext::ncurses.addStr(str.c_str());
|
||||
ext::ncurses.refresh();
|
||||
return str;
|
||||
#endif
|
||||
return str;
|
||||
}
|
||||
const uf::String& UF_API_CALL uf::IoStream::writeUString( const uf::String& str ) {
|
||||
#if UF_USE_NCURSES
|
||||
@ -450,13 +456,14 @@ const uf::String& UF_API_CALL uf::IoStream::writeUString( const uf::String& str
|
||||
*/
|
||||
if ( !uf::IoStream::ncurses ) {
|
||||
std::cout << (const char*) str.getString().c_str();
|
||||
::info.input.history.push_back( str );
|
||||
return str;
|
||||
}
|
||||
#if UF_USE_NCURSES
|
||||
ext::ncurses.addStr((const char*) str.getString().c_str());
|
||||
ext::ncurses.refresh();
|
||||
return str;
|
||||
#endif
|
||||
return str;
|
||||
}
|
||||
|
||||
void UF_API_CALL uf::IoStream::operator>> (bool& val) {
|
||||
|
@ -68,12 +68,13 @@ void uf::memoryPool::initialize( pod::MemoryPool& pool, size_t size ) {
|
||||
pool.size = size;
|
||||
}
|
||||
void uf::memoryPool::destroy( pod::MemoryPool& pool ) {
|
||||
if ( uf::memoryPool::size( pool ) <= 0 ) return;
|
||||
if ( uf::memoryPool::size( pool ) <= 0 ) goto CLEAR;
|
||||
if ( uf::memoryPool::subPool && &pool != &uf::memoryPool::global.data() ) {
|
||||
uf::memoryPool::global.free( pool.memory );
|
||||
} else {
|
||||
uf::allocator::free_m(pool.memory);
|
||||
}
|
||||
CLEAR:
|
||||
pool.size = 0;
|
||||
pool.memory = NULL;
|
||||
}
|
||||
@ -243,6 +244,9 @@ bool uf::memoryPool::exists( pod::MemoryPool& pool, void* pointer, size_t size )
|
||||
#endif
|
||||
}
|
||||
bool uf::memoryPool::free( pod::MemoryPool& pool, void* pointer, size_t size ) {
|
||||
// skip freeing, we're already a deallocated pool
|
||||
// this comes up because of how backasswards C++ static initialization/destruction order is
|
||||
if ( !pool.memory ) return false;
|
||||
// passed a NULL, for some reason
|
||||
if ( !pointer ) return false;
|
||||
#if UF_MEMORYPOOL_MUTEX
|
||||
|
@ -9,6 +9,12 @@
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
|
||||
#define UF_SERIALIZER_IMPLICIT_LOAD 1
|
||||
#define UF_SERIALIZER_AUTO_CONVERT 1
|
||||
|
||||
//#define UF_MSG_DEBUG_(...) UF_MSG_DEBUG(__VA_ARGS__)
|
||||
#define UF_MSG_DEBUG_(...)
|
||||
|
||||
uf::Serializer::Serializer( const uf::stl::string& str ) { //: sol::table(ext::lua::state, sol::create) {
|
||||
this->deserialize(str);
|
||||
}
|
||||
@ -31,14 +37,37 @@ uf::Serializer::output_t uf::Serializer::serialize( bool pretty ) const {
|
||||
uf::Serializer::output_t uf::Serializer::serialize( const ext::json::EncodingSettings& settings ) const {
|
||||
return ext::json::encode( *this, settings );
|
||||
}
|
||||
void uf::Serializer::deserialize( const uf::stl::string& str ) {
|
||||
void uf::Serializer::deserialize( const uf::stl::string& str, const ext::json::DecodingSettings& settings ) {
|
||||
if ( str == "" ) return;
|
||||
ext::json::decode( *this, str );
|
||||
ext::json::decode( *this, str, settings );
|
||||
}
|
||||
|
||||
uf::stl::string uf::Serializer::resolveFilename( const uf::stl::string& filename, bool compareTimes ) {
|
||||
uf::stl::string _filename = filename;
|
||||
if ( ext::json::PREFERRED_ENCODING != "" && ext::json::PREFERRED_ENCODING != "json" ) {
|
||||
_filename = uf::string::replace( _filename, "/.json$/", "." + ext::json::PREFERRED_ENCODING );
|
||||
}
|
||||
if ( ext::json::PREFERRED_COMPRESSION != "" ) {
|
||||
_filename = _filename + "." + ext::json::PREFERRED_COMPRESSION;
|
||||
}
|
||||
if ( !compareTimes ) return _filename;
|
||||
|
||||
if ( uf::io::exists( _filename ) ) {
|
||||
bool should = !uf::io::exists( filename ); // implicit load if our requested filename doesnt exist anyways, but our preferred source does
|
||||
if ( !should ) should = uf::io::mtime( _filename ) > uf::io::mtime( filename ); // implicit load the preferred source is newer than the requested filename
|
||||
if ( should ) return _filename;
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
bool uf::Serializer::readFromFile( const uf::stl::string& filename, const uf::stl::string& hash ) {
|
||||
uf::String string;
|
||||
// uf::stl::string filename = _filename + ( uf::io::exists(_filename + ".gz") ? ".gz" : "" );
|
||||
#if UF_SERIALIZER_IMPLICIT_LOAD
|
||||
// implicitly check for optimal format for plain .json requests
|
||||
if ( uf::string::matched( filename, "/.json$/" ) ) {
|
||||
uf::stl::string _filename = uf::Serializer::resolveFilename( filename );
|
||||
if ( _filename != filename ) return readFromFile( _filename, hash );
|
||||
}
|
||||
#endif
|
||||
bool exists = uf::io::exists( filename );
|
||||
if ( !exists ) {
|
||||
UF_MSG_ERROR("Failed to read JSON file `" << filename << "`: does not exist");
|
||||
@ -50,17 +79,78 @@ bool uf::Serializer::readFromFile( const uf::stl::string& filename, const uf::st
|
||||
return false;
|
||||
}
|
||||
|
||||
this->m_filename = filename;
|
||||
|
||||
/*
|
||||
uf::String string;
|
||||
auto& str = string.getString();
|
||||
str.reserve(buffer.size());
|
||||
str.assign(buffer.begin(), buffer.end());
|
||||
*/
|
||||
uf::stl::string string{ buffer.begin(), buffer.end() };
|
||||
|
||||
ext::json::DecodingSettings settings;
|
||||
if ( uf::string::matched( filename, "/.bson/" ) ) settings.encoding = "bson";
|
||||
else if ( uf::string::matched( filename, "/.cbor/" ) ) settings.encoding = "cbor";
|
||||
this->deserialize( string, settings );
|
||||
|
||||
#if UF_SERIALIZER_AUTO_CONVERT
|
||||
if ( uf::string::matched( filename, "/.json$/" ) ) {
|
||||
if ( ext::json::PREFERRED_COMPRESSION != "" || (ext::json::PREFERRED_ENCODING != "" || ext::json::PREFERRED_ENCODING != "json") ) {
|
||||
ext::json::EncodingSettings _settings;
|
||||
_settings.encoding = ext::json::PREFERRED_ENCODING;
|
||||
_settings.compression = ext::json::PREFERRED_COMPRESSION;
|
||||
uf::stl::string _filename = filename;
|
||||
|
||||
if ( ext::json::PREFERRED_ENCODING != "" && ext::json::PREFERRED_ENCODING != "json" ) {
|
||||
_settings.encoding = ext::json::PREFERRED_ENCODING;
|
||||
_filename = uf::string::replace( _filename, "/.json$/", "." + ext::json::PREFERRED_ENCODING );
|
||||
}
|
||||
if ( ext::json::PREFERRED_COMPRESSION != "" ) {
|
||||
_settings.compression = ext::json::PREFERRED_COMPRESSION;
|
||||
_filename = _filename + "." + ext::json::PREFERRED_COMPRESSION;
|
||||
}
|
||||
bool should = !uf::io::exists( _filename ); // auto convert if preferred file doesn't already exist
|
||||
if ( !should ) should = uf::io::mtime( _filename ) < uf::io::mtime( filename ); // auto convert if preferred file is older than source file
|
||||
if ( should ) {
|
||||
UF_MSG_DEBUG_("Auto converting: " << _filename );
|
||||
writeToFile( _filename, _settings );
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
this->deserialize(string);
|
||||
return true;
|
||||
}
|
||||
bool uf::Serializer::writeToFile( const uf::stl::string& filename, const ext::json::EncodingSettings& settings ) const {
|
||||
uf::stl::string output = filename;
|
||||
|
||||
if ( settings.encoding != "" && settings.encoding != "json" )
|
||||
output = uf::string::replace( output, "/.json/", "." + settings.encoding );
|
||||
if ( settings.compression != "" && !uf::string::matched( output, "/."+settings.compression+"/" ) )
|
||||
output += "." + settings.compression;
|
||||
|
||||
uf::stl::string buffer = this->serialize( settings );
|
||||
size_t written = uf::io::write( filename + ( settings.compress ? ".gz" : "" ) , buffer.c_str(), buffer.size() );
|
||||
if ( !written ) UF_MSG_ERROR("Failed to write JSON file `" << filename << "`");
|
||||
size_t written = uf::io::write( output, buffer.c_str(), buffer.size() );
|
||||
#if UF_SERIALIZER_AUTO_CONVERT
|
||||
// implicitly check for optimal format for plain .json requests
|
||||
if ( uf::string::matched( output, "/.json$/" ) && settings.compression != ext::json::PREFERRED_COMPRESSION ) {
|
||||
uf::stl::string _filename = output;
|
||||
auto _settings = settings;
|
||||
|
||||
if ( ext::json::PREFERRED_ENCODING != "" && ext::json::PREFERRED_ENCODING != "json" ) {
|
||||
_settings.encoding = ext::json::PREFERRED_ENCODING;
|
||||
// _filename = uf::string::replace( _filename, "/.json$/", "." + ext::json::PREFERRED_ENCODING );
|
||||
}
|
||||
if ( ext::json::PREFERRED_COMPRESSION != "" ) {
|
||||
_settings.compression = ext::json::PREFERRED_COMPRESSION;
|
||||
// _filename = _filename + "." + ext::json::PREFERRED_COMPRESSION;
|
||||
}
|
||||
writeToFile( _filename, _settings );
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( !written ) UF_MSG_ERROR("Failed to write JSON file: " << output);
|
||||
return written;
|
||||
}
|
||||
|
||||
|
@ -18,8 +18,7 @@ bool UF_API uf::string::match( const uf::stl::string& str, const uf::stl::string
|
||||
bool UF_API uf::string::isRegex( const uf::stl::string& str ) {
|
||||
return str.front() == '/' && str.back() == '/';
|
||||
}
|
||||
uf::stl::vector<uf::stl::string> UF_API uf::string::matches( const uf::stl::string& str, const uf::stl::string& r ) {
|
||||
|
||||
uf::stl::vector<uf::stl::string> UF_API uf::string::match( const uf::stl::string& str, const uf::stl::string& r ) {
|
||||
std::regex regex(r.substr(1,r.length()-2));
|
||||
std::smatch match;
|
||||
uf::stl::vector<uf::stl::string> matches;
|
||||
@ -31,6 +30,11 @@ uf::stl::vector<uf::stl::string> UF_API uf::string::matches( const uf::stl::stri
|
||||
|
||||
return matches;
|
||||
}
|
||||
bool UF_API uf::string::matched( const uf::stl::string& str, const uf::stl::string& r ) {
|
||||
std::regex regex(r.substr(1,r.length()-2));
|
||||
std::smatch match;
|
||||
return std::regex_search( str, match, regex );
|
||||
}
|
||||
|
||||
uf::stl::string UF_API uf::string::lowercase( const uf::stl::string& str ) {
|
||||
uf::stl::string lower = str;
|
||||
@ -78,9 +82,15 @@ uf::stl::string UF_API uf::string::join( const uf::stl::vector<uf::stl::string>&
|
||||
*/
|
||||
uf::stl::string UF_API uf::string::replace( const uf::stl::string& string, const uf::stl::string& search, const uf::stl::string& replace ) {
|
||||
uf::stl::string result = string;
|
||||
size_t start_pos = string.find(search);
|
||||
if( start_pos == uf::stl::string::npos ) return result;
|
||||
result.replace(start_pos, search.length(), replace);
|
||||
|
||||
if ( uf::string::isRegex(search) ) {
|
||||
std::regex regex(search.substr(1,search.length()-2));
|
||||
result = std::regex_replace( string, regex, replace );
|
||||
} else {
|
||||
size_t start_pos = string.find(search);
|
||||
if( start_pos == uf::stl::string::npos ) return result;
|
||||
result.replace(start_pos, search.length(), replace);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
bool UF_API uf::string::contains( const uf::stl::string& string, const uf::stl::string& search ) {
|
||||
|
@ -156,7 +156,10 @@ SAVE: {
|
||||
payload["uid"] = this->getUid();
|
||||
uf::scene::getCurrentScene().queueHook("system:Destroy", payload);
|
||||
|
||||
if ( metadata.trigger.quits ) uf::scene::getCurrentScene().queueHook("system:Quit", payload);
|
||||
if ( metadata.trigger.quits ) {
|
||||
payload["message"] = "Termination after lightmap baking requested.";
|
||||
uf::scene::getCurrentScene().queueHook("system:Quit", payload);
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
@ -79,7 +79,9 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
|
||||
// Rotate Camera
|
||||
this->addHook( "window:Mouse.Moved", [&](pod::payloads::windowMouseMoved& payload ){
|
||||
pod::Vector2 relta = { (float) metadata.mouse.sensitivity.x * payload.mouse.delta.x / payload.window.size.x, (float) metadata.mouse.sensitivity.y * payload.mouse.delta.y / payload.window.size.y };
|
||||
// pod::Vector2 relta = { (float) metadata.mouse.sensitivity.x * payload.mouse.delta.x * uf::physics::time::delta, (float) metadata.mouse.sensitivity.y * payload.mouse.delta.y * uf::physics::time::delta };
|
||||
if ( (payload.mouse.delta.x == 0 && payload.mouse.delta.y == 0) || !metadata.system.control ) return;
|
||||
// relta *= uf::physics::time::delta;
|
||||
|
||||
if ( payload.mouse.delta.x != 0 ) {
|
||||
if ( metadata.camera.invert.x ) relta.x *= -1;
|
||||
@ -93,11 +95,8 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
|
||||
if ( metadata.camera.invert.y ) relta.y *= -1;
|
||||
metadata.camera.limit.current.y += relta.y;
|
||||
if ( metadata.camera.limit.current.y != metadata.camera.limit.current.y || ( metadata.camera.limit.current.y < metadata.camera.limit.max.y && metadata.camera.limit.current.y > metadata.camera.limit.min.y ) ) {
|
||||
// if ( collider.body && !collider.shared ) {
|
||||
// uf::physics::impl::applyRotation( collider, cameraTransform.right, relta.y );
|
||||
// } else {
|
||||
// if ( collider.body && !collider.shared ) uf::physics::impl::applyRotation( collider, cameraTransform.right, relta.y ); else
|
||||
uf::transform::rotate( cameraTransform, cameraTransform.right, relta.y );
|
||||
// }
|
||||
} else metadata.camera.limit.current.y -= relta.y;
|
||||
}
|
||||
camera.update(true);
|
||||
|
@ -566,6 +566,7 @@ void ext::ExtSceneBehavior::Metadata::serialize( uf::Object& self, uf::Serialize
|
||||
serializer["light"]["exposure"] = /*this->*/light.exposure;
|
||||
serializer["light"]["gamma"] = /*this->*/light.gamma;
|
||||
serializer["light"]["brightnessThreshold"] = /*this->*/light.brightnessThreshold;
|
||||
serializer["light"]["useLightmaps"] = /*this->*/light.useLightmaps;
|
||||
|
||||
serializer["light"]["fog"]["color"] = uf::vector::encode( /*this->*/fog.color );
|
||||
serializer["light"]["fog"]["step scale"] = /*this->*/fog.stepScale;
|
||||
@ -600,6 +601,7 @@ void ext::ExtSceneBehavior::Metadata::deserialize( uf::Object& self, uf::Seriali
|
||||
/*this->*/light.exposure = serializer["light"]["exposure"].as<float>(1.0f);
|
||||
/*this->*/light.gamma = serializer["light"]["gamma"].as<float>(2.2f);
|
||||
/*this->*/light.brightnessThreshold = serializer["light"]["brightnessThreshold"].as<float>(ext::config["engine"]["scenes"]["bloom"]["brightnessThreshold"].as<float>(1.0f));
|
||||
/*this->*/light.useLightmaps = ext::config["engine"]["scenes"]["lights"]["useLightmaps"].as<bool>(true);
|
||||
|
||||
/*this->*/bloom.scale = serializer["bloom"]["scale"].as(ext::config["engine"]["scenes"]["bloom"]["scale"].as(bloom.scale));
|
||||
/*this->*/bloom.strength = serializer["bloom"]["strength"].as(ext::config["engine"]["scenes"]["bloom"]["strength"].as(bloom.strength));
|
||||
@ -740,7 +742,7 @@ void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, const uf::stl::string
|
||||
alignas(4) uint32_t shadowSamples;
|
||||
|
||||
alignas(4) uint32_t indexSkybox;
|
||||
alignas(4) uint32_t padding1;
|
||||
alignas(4) uint32_t useLightmaps;
|
||||
alignas(4) uint32_t padding2;
|
||||
alignas(4) uint32_t padding3;
|
||||
};
|
||||
@ -839,6 +841,8 @@ void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, const uf::stl::string
|
||||
uniforms.shadowSamples = std::min( 0, metadata.shadow.samples );
|
||||
|
||||
uniforms.indexSkybox = indexSkybox;
|
||||
// use sample lightmaps during deferred pass
|
||||
uniforms.useLightmaps = metadata.light.useLightmaps;
|
||||
}
|
||||
|
||||
for ( auto* blitter : blitters ) {
|
||||
|
@ -25,6 +25,7 @@ namespace ext {
|
||||
float exposure = 1.0f;
|
||||
float gamma = 1.0f;
|
||||
float brightnessThreshold = 1.0f;
|
||||
bool useLightmaps = true;
|
||||
} light;
|
||||
struct {
|
||||
float scale = 1.0f;
|
||||
|
10
ext/main.cpp
10
ext/main.cpp
@ -95,7 +95,7 @@ namespace {
|
||||
}
|
||||
|
||||
void EXT_API ext::load() {
|
||||
ext::config = uf::io::readAsString(uf::io::root+"/config.json");
|
||||
ext::config.readFromFile(uf::io::root+"/config.json");
|
||||
}
|
||||
void EXT_API ext::initialize() {
|
||||
|
||||
@ -555,6 +555,9 @@ void EXT_API ext::initialize() {
|
||||
uf::scene::unloadScene();
|
||||
});
|
||||
uf::hooks.addHook( "system:Quit", [&](ext::json::Value& json){
|
||||
if ( json["message"].is<uf::stl::string>() ) {
|
||||
UF_MSG_DEBUG( json["message"].as<uf::stl::string>() );
|
||||
}
|
||||
ext::ready = false;
|
||||
});
|
||||
}
|
||||
@ -732,6 +735,9 @@ void EXT_API ext::terminate() {
|
||||
ext::openvr::terminate();
|
||||
}
|
||||
#endif
|
||||
{
|
||||
uf::hooks.removeHooks();
|
||||
}
|
||||
#if UF_USE_LUA
|
||||
{
|
||||
ext::lua::terminate();
|
||||
@ -744,7 +750,7 @@ void EXT_API ext::terminate() {
|
||||
uf::scene::destroy();
|
||||
}
|
||||
|
||||
/* Garbage collection */ if ( false ) {
|
||||
/* Garbage collection */ if ( false ) { // segfaults, for some reason
|
||||
size_t collected = uf::instantiator::collect( ::config.engine.gc.mode );
|
||||
if ( ::config.engine.gc.announce && collected > 0 ) UF_MSG_DEBUG("GC collected " << (int) collected << " unused entities");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user