Commit for 2020.11.09.7z

This commit is contained in:
mrq 2020-11-09 00:00:00 -06:00
parent 2b56261e73
commit ed8eacc719
122 changed files with 7024 additions and 9959 deletions

View File

@ -1,5 +1,5 @@
DEFAULT_PREFIX = gcc
include makefiles/win64.$(DEFAULT_PREFIX).make
PREFIX = gcc
include makefiles/win64.$(PREFIX).make
.PHONY: $(ARCH)-$(PREFIX)
@ -15,15 +15,15 @@ CLIENT_SRC_DIR += ./client
UF_LIBS +=
EXT_LIBS +=
FLAGS += -std=c++17 -DVK_USE_PLATFORM_WIN32_KHR -DUF_USE_VULKAN -DGLM_ENABLE_EXPERIMENTAL -DUF_USE_JSON -DUF_USE_NCURSES -DUF_USE_OPENAL -DUF_USE_VORBIS -DUF_USE_FREETYPE -DUSE_OPENVR_MINGW
FLAGS += -Wno-unknown-pragmas -std=c++17 -g -DVK_USE_PLATFORM_WIN32_KHR -DUF_USE_VULKAN -DGLM_ENABLE_EXPERIMENTAL -DUF_USE_JSON -DUF_USE_NCURSES -DUF_USE_OPENAL -DUF_USE_VORBIS -DUF_USE_FREETYPE -DUSE_OPENVR_MINGW
LIB_NAME += uf
EXT_LIB_NAME += ext
#VULKAN_SDK_PATH += /c/VulkanSDK/1.1.101.0/
#VULKAN_SDK_PATH += /c/VulkanSDK/1.1.108.0/
#VULKAN_SDK_PATH += /c/VulkanSDK/1.1.114.0/
VULKAN_SDK_PATH += /c/VulkanSDK/1.2.141.2/
#VULKAN_SDK_PATH += /c/VulkanSDK/1.2.154.0/
#VULKAN_SDK_PATH += /c/VulkanSDK/1.2.141.2/
VULKAN_SDK_PATH += /c/VulkanSDK/1.2.154.0/
GLSL_VALIDATOR += $(VULKAN_SDK_PATH)/Bin32/glslangValidator
# Base Engine's DLL
INC_DIR += $(ENGINE_INC_DIR)/$(ARCH)/$(PREFIX)
@ -41,13 +41,12 @@ SRCS_DLL += $(wildcard $(ENGINE_SRC_DIR)/*.cpp) $(wildcard $(ENGINE_SRC_DIR)
OBJS_DLL += $(patsubst %.cpp,%.$(ARCH).$(PREFIX).o,$(SRCS_DLL))
BASE_DLL += lib$(LIB_NAME)
IM_DLL += $(ENGINE_LIB_DIR)/$(ARCH)/$(PREFIX)/$(BASE_DLL).dll.a
EX_DLL += $(BIN_DIR)/lib/$(ARCH)/$(PREFIX)/$(BASE_DLL).dll
EX_DLL += $(BIN_DIR)/exe/lib/$(ARCH)/$(PREFIX)/$(BASE_DLL).dll
# External Engine's DLL
EXT_INC_DIR += $(INC_DIR)
EXT_LB_FLAGS += $(LIB_DIR)
EXT_DEPS += -l$(LIB_NAME) $(DEPS)
EXT_LINKS += $(UF_LIBS) $(EXT_LIBS) $(EXT_DEPS)
EXT_FLAGS += $(FLAGS)
#-Wl,-subsystem,windows
EXT_LIB_DIR += $(ENGINE_LIB_DIR)/$(ARCH)/$(PREFIX)/
@ -58,11 +57,11 @@ SRCS_EXT_DLL += $(wildcard $(EXT_SRC_DIR)/*.cpp) $(wildcard $(EXT_SRC_DIR)/*/
OBJS_EXT_DLL += $(patsubst %.cpp,%.$(ARCH).$(PREFIX).o,$(SRCS_EXT_DLL))
BASE_EXT_DLL += lib$(EXT_LIB_NAME)
EXT_IM_DLL += $(ENGINE_LIB_DIR)/$(ARCH)/$(PREFIX)/$(BASE_EXT_DLL).dll.a
EXT_EX_DLL += $(BIN_DIR)/lib/$(ARCH)/$(PREFIX)/$(BASE_EXT_DLL).dll
EXT_EX_DLL += $(BIN_DIR)/exe/lib/$(ARCH)/$(PREFIX)/$(BASE_EXT_DLL).dll
# Client EXE
SRCS += $(wildcard $(CLIENT_SRC_DIR)/*.cpp) $(wildcard $(CLIENT_SRC_DIR)/*/*.cpp)
OBJS += $(patsubst %.cpp,%.$(ARCH).$(PREFIX).o,$(SRCS))
TARGET += $(BIN_DIR)/$(TARGET_NAME).$(PREFIX).exe
TARGET += $(BIN_DIR)/exe/$(TARGET_NAME).$(PREFIX).exe
# Shaders
SRCS_SHADERS += $(wildcard bin/data/shaders/*.glsl)
TARGET_SHADERS += $(patsubst %.glsl,%.spv,$(SRCS_SHADERS))
@ -78,12 +77,12 @@ rm-exe64:
%.$(ARCH).$(PREFIX).o: %.cpp
$(CC) $(FLAGS) $(INCS) -c $< -o $@
$(EX_DLL): FLAGS += -DUF_EXPORTS
$(EX_DLL): FLAGS += -DUF_EXPORTS -DJSON_DLL_BUILD
$(EX_DLL): $(OBJS_DLL)
$(CC) -shared -o $(EX_DLL) -g -Wl,--out-implib=$(IM_DLL) $(OBJS_DLL) $(LIBS) $(INCS) $(LINKS)
cp $(ENGINE_LIB_DIR)/$(ARCH)/$(PREFIX)/$(BASE_DLL).dll.a $(ENGINE_LIB_DIR)/$(ARCH)/$(PREFIX)/$(BASE_DLL).a
$(EXT_EX_DLL): FLAGS += -DEXT_EXPORTS
$(EXT_EX_DLL): FLAGS += -DEXT_EXPORTS -DJSON_DLL_BUILD
$(EXT_EX_DLL): $(OBJS_EXT_DLL)
$(CC) -shared -o $(EXT_EX_DLL) -g -Wl,--out-implib=$(EXT_IM_DLL) $(OBJS_EXT_DLL) $(EXT_LIBS) $(EXT_INCS) $(EXT_LINKS)
cp $(ENGINE_LIB_DIR)/$(ARCH)/$(PREFIX)/$(BASE_EXT_DLL).dll.a $(ENGINE_LIB_DIR)/$(ARCH)/$(PREFIX)/$(BASE_EXT_DLL).a

View File

@ -26,7 +26,6 @@ void main() {
outAlbedoSpecular = texture(sampler2D(albedoTexture, samp), uv);
outNormal = texture(sampler2D(normalTexture, samp), uv);
outPosition = texture(sampler2D(positionTexture, samp), uv);
// if ( outAlbedoSpecular.a < 0.01f ) outAlbedoSpecular = vec4(0,0,0,1);
return;
}

View File

@ -31,8 +31,6 @@ void main() {
return;
}
float dist = texture(samplerColor, inUv).r;
// outFragColor = mix(vec4(inGui.color) * dist, vec4(1.0f, 0.0f, 1.0f, 0.5f), 0.9);
if ( inGui.sdf == 1 ) {
float smoothing = ( inGui.spread > 0 && inGui.scale > 0 ) ? 0.25 / (inGui.spread * inGui.scale) : 0.25 / (4 * 1.5);
float outlining = smoothstep(0.5 - smoothing, 0.5 + smoothing, dist);

View File

@ -34,8 +34,8 @@ void client::initialize() {
/* Initialize window */ {
// Window size
pod::Vector2i size; {
size.x = client::config["window"]["size"]["x"].asUInt();
size.y = client::config["window"]["size"]["y"].asUInt();
size.x = client::config["window"]["size"]["x"].as<size_t>();
size.y = client::config["window"]["size"]["y"].as<size_t>();
// request system size
if ( size.x <= 0 && size.y <= 0 ) {
auto resolution = client::window.getResolution();
@ -45,12 +45,12 @@ void client::initialize() {
}
// Window title
uf::String title; {
title = client::config["window"]["title"].asString();
title = client::config["window"]["title"].as<std::string>();
}
// Terminal window;
spec::terminal.setVisible( client::config["window"]["terminal"]["visible"].asBool() );
spec::terminal.setVisible( client::config["window"]["terminal"]["visible"].as<bool>() );
// Ncurses
uf::IoStream::ncurses = client::config["window"]["terminal"]["ncurses"].asBool();
uf::IoStream::ncurses = client::config["window"]["terminal"]["ncurses"].as<bool>();
// Window's context settings
uf::renderer::settings::width = size.x;
@ -58,16 +58,16 @@ void client::initialize() {
client::window.create( size, title );
// Miscellaneous
client::window.setVisible(client::config["window"]["visible"].asBool());
client::window.setCursorVisible(client::config["window"]["cursor"]["visible"].asBool());
client::window.setKeyRepeatEnabled(client::config["window"]["keyboard"]["repeat"].asBool());
client::window.setVisible(client::config["window"]["visible"].as<bool>());
client::window.setCursorVisible(client::config["window"]["cursor"]["visible"].as<bool>());
client::window.setKeyRepeatEnabled(client::config["window"]["keyboard"]["repeat"].as<bool>());
// client::window.centerWindow();
// client::window.setPosition({0, 0});
// client::window.setMouseGrabbed(true);
/* Set Icon */ if ( client::config["window"]["icon"].isString() ) {
/* Set Icon */ if ( client::config["window"]["icon"].is<std::string>() ) {
uf::Image icon;
icon.open(client::config["window"]["icon"].asString());
icon.open(client::config["window"]["icon"].as<std::string>());
client::window.setIcon({(int) icon.getDimensions().x, (int) icon.getDimensions().y}, ((uint8_t*)icon.getPixelsPtr()));
}
client::window.setTitle(title); {
@ -94,10 +94,10 @@ void client::initialize() {
if ( client::config["engine"]["hook"]["mode"] == "Both" || client::config["engine"]["hook"]["mode"] == "Readable" ) {
uf::hooks.addHook( "window:Mouse.CursorVisibility", [&](const std::string& event)->std::string{
uf::Serializer json = event;
client::window.setCursorVisible(json["state"].asBool());
client::window.setMouseGrabbed(!json["state"].asBool());
client::config["mouse"]["visible"] = json["state"].asBool();
client::config["window"]["mouse"]["center"] = !json["state"].asBool();
client::window.setCursorVisible(json["state"].as<bool>());
client::window.setMouseGrabbed(!json["state"].as<bool>());
client::config["mouse"]["visible"] = json["state"].as<bool>();
client::config["window"]["mouse"]["center"] = !json["state"].as<bool>();
return "true";
});
uf::hooks.addHook( "window:Mouse.Lock", [&](const std::string& event)->std::string{
@ -115,8 +115,8 @@ void client::initialize() {
uf::hooks.addHook( "window:Title.Changed", [&](const std::string& event)->std::string{
uf::Serializer json = event;
if ( json["invoker"] != "os" ) {
if ( !json["window"].isObject() ) return "false";
uf::String title = json["window"]["title"].asString();
if ( !ext::json::isObject( json["window"] ) ) return "false";
uf::String title = json["window"]["title"].as<std::string>();
client::window.setTitle(title);
}
return "true";
@ -124,15 +124,15 @@ void client::initialize() {
uf::hooks.addHook( "window:Resized", [&](const std::string& event)->std::string{
uf::Serializer json = event;
pod::Vector2i size; {
size.x = json["window"]["size"]["x"].asUInt64();
size.y = json["window"]["size"]["y"].asUInt64();
size.x = json["window"]["size"]["x"].as<size_t>();
size.y = json["window"]["size"]["y"].as<size_t>();
}
if ( json["invoker"] != "os" ) {
client::window.setSize(size);
}
// Update viewport
if ( !client::config["engine"]["ext"]["vulkan"]["framebuffer"]["size"].isArray() ) {
float scale = client::config["engine"]["ext"]["vulkan"]["framebuffer"]["size"].isNumeric() ? client::config["engine"]["ext"]["vulkan"]["framebuffer"]["size"].asFloat() : 1;
if ( !ext::json::isArray( client::config["engine"]["ext"]["vulkan"]["framebuffer"]["size"] ) ) {
float scale = client::config["engine"]["ext"]["vulkan"]["framebuffer"]["size"].is<double>() ? client::config["engine"]["ext"]["vulkan"]["framebuffer"]["size"].as<float>() : 1;
uf::renderer::settings::width = size.x * scale;
uf::renderer::settings::height = size.y * scale;
}
@ -182,8 +182,8 @@ void client::initialize() {
} );
}
}
if ( client::config["window"]["mode"].asString() == "fullscreen" ) client::window.switchToFullscreen();
if ( client::config["window"]["mode"].asString() == "borderless" ) client::window.switchToFullscreen( true );
if ( client::config["window"]["mode"].as<std::string>() == "fullscreen" ) client::window.switchToFullscreen();
if ( client::config["window"]["mode"].as<std::string>() == "borderless" ) client::window.switchToFullscreen( true );
client::ready = true;
}
void client::tick() {
@ -191,7 +191,7 @@ void client::tick() {
client::window.pollEvents();
// call mouse move
// query lock
if ( client::window.hasFocus() && client::config["window"]["mouse"]["center"].asBool() ) {
if ( client::window.hasFocus() && client::config["window"]["mouse"]["center"].as<bool>() ) {
auto previous = client::window.getMousePosition();
client::window.setMousePosition(client::window.getSize()/2);
auto current = client::window.getMousePosition();

View File

@ -1,8 +1,7 @@
#!/bin/bash
PREFIX=gcc
cd bin
cp lib/win64/$PREFIX/*.dll .
gdb program.$PREFIX.exe
PREFIX=$(cat ./exe/default.config)
cp ./exe/lib/win64/$PREFIX/*.dll .
gdb ./exe/program.$PREFIX.exe
rm *.dll

View File

@ -0,0 +1,15 @@
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef JSON_JSON_H_INCLUDED
#define JSON_JSON_H_INCLUDED
#include "autolink.h"
#include "value.h"
#include "reader.h"
#include "writer.h"
#include "features.h"
#endif // JSON_JSON_H_INCLUDED

View File

@ -0,0 +1,446 @@
/// Json-cpp amalgamated forward header (http://jsoncpp.sourceforge.net/).
/// It is intended to be used with #include "json/json-forwards.h"
/// This header provides forward declaration for all JsonCpp types.
// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: LICENSE
// //////////////////////////////////////////////////////////////////////
/*
The JsonCpp library's source code, including accompanying documentation,
tests and demonstration applications, are licensed under the following
conditions...
Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all
jurisdictions which recognize such a disclaimer. In such jurisdictions,
this software is released into the Public Domain.
In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and
The JsonCpp Authors, and is released under the terms of the MIT License (see below).
In jurisdictions which recognize Public Domain property, the user of this
software may choose to accept it either as 1) Public Domain, 2) under the
conditions of the MIT License (see below), or 3) under the terms of dual
Public Domain/MIT License conditions described here, as they choose.
The MIT License is about as close to Public Domain as a license can get, and is
described in clear, concise terms at:
http://en.wikipedia.org/wiki/MIT_License
The full text of the MIT License follows:
========================================================================
Copyright (c) 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
========================================================================
(END LICENSE TEXT)
The MIT license is compatible with both the GPL and commercial
software, affording one all of the rights of Public Domain with the
minor nuisance of being required to keep the above copyright notice
and license text in the source code. Note also that by accepting the
Public Domain "license" you can re-license your copy using whatever
license you like.
*/
// //////////////////////////////////////////////////////////////////////
// End of content of file: LICENSE
// //////////////////////////////////////////////////////////////////////
#ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED
# define JSON_FORWARD_AMALGAMATED_H_INCLUDED
/// If defined, indicates that the source file is amalgamated
/// to prevent private header inclusion.
#define JSON_IS_AMALGAMATION
// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: include/json/version.h
// //////////////////////////////////////////////////////////////////////
#ifndef JSON_VERSION_H_INCLUDED
#define JSON_VERSION_H_INCLUDED
// Note: version must be updated in three places when doing a release. This
// annoying process ensures that amalgamate, CMake, and meson all report the
// correct version.
// 1. /meson.build
// 2. /include/json/version.h
// 3. /CMakeLists.txt
// IMPORTANT: also update the SOVERSION!!
#define JSONCPP_VERSION_STRING "1.9.4"
#define JSONCPP_VERSION_MAJOR 1
#define JSONCPP_VERSION_MINOR 9
#define JSONCPP_VERSION_PATCH 4
#define JSONCPP_VERSION_QUALIFIER
#define JSONCPP_VERSION_HEXA \
((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \
(JSONCPP_VERSION_PATCH << 8))
#ifdef JSONCPP_USING_SECURE_MEMORY
#undef JSONCPP_USING_SECURE_MEMORY
#endif
#define JSONCPP_USING_SECURE_MEMORY 0
// If non-zero, the library zeroes any memory that it has allocated before
// it frees its memory.
#endif // JSON_VERSION_H_INCLUDED
// //////////////////////////////////////////////////////////////////////
// End of content of file: include/json/version.h
// //////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: include/json/allocator.h
// //////////////////////////////////////////////////////////////////////
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef JSON_ALLOCATOR_H_INCLUDED
#define JSON_ALLOCATOR_H_INCLUDED
#include <cstring>
#include <memory>
#pragma pack(push, 8)
namespace Json {
template <typename T> class SecureAllocator {
public:
// Type definitions
using value_type = T;
using pointer = T*;
using const_pointer = const T*;
using reference = T&;
using const_reference = const T&;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
/**
* Allocate memory for N items using the standard allocator.
*/
pointer allocate(size_type n) {
// allocate using "global operator new"
return static_cast<pointer>(::operator new(n * sizeof(T)));
}
/**
* Release memory which was allocated for N items at pointer P.
*
* The memory block is filled with zeroes before being released.
*/
void deallocate(pointer p, size_type n) {
// memset_s is used because memset may be optimized away by the compiler
memset_s(p, n * sizeof(T), 0, n * sizeof(T));
// free using "global operator delete"
::operator delete(p);
}
/**
* Construct an item in-place at pointer P.
*/
template <typename... Args> void construct(pointer p, Args&&... args) {
// construct using "placement new" and "perfect forwarding"
::new (static_cast<void*>(p)) T(std::forward<Args>(args)...);
}
size_type max_size() const { return size_t(-1) / sizeof(T); }
pointer address(reference x) const { return std::addressof(x); }
const_pointer address(const_reference x) const { return std::addressof(x); }
/**
* Destroy an item in-place at pointer P.
*/
void destroy(pointer p) {
// destroy using "explicit destructor"
p->~T();
}
// Boilerplate
SecureAllocator() {}
template <typename U> SecureAllocator(const SecureAllocator<U>&) {}
template <typename U> struct rebind { using other = SecureAllocator<U>; };
};
template <typename T, typename U>
bool operator==(const SecureAllocator<T>&, const SecureAllocator<U>&) {
return true;
}
template <typename T, typename U>
bool operator!=(const SecureAllocator<T>&, const SecureAllocator<U>&) {
return false;
}
} // namespace Json
#pragma pack(pop)
#endif // JSON_ALLOCATOR_H_INCLUDED
// //////////////////////////////////////////////////////////////////////
// End of content of file: include/json/allocator.h
// //////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: include/json/config.h
// //////////////////////////////////////////////////////////////////////
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef JSON_CONFIG_H_INCLUDED
#define JSON_CONFIG_H_INCLUDED
#include <cstddef>
#include <cstdint>
#include <istream>
#include <memory>
#include <ostream>
#include <sstream>
#include <string>
#include <type_traits>
// If non-zero, the library uses exceptions to report bad input instead of C
// assertion macros. The default is to use exceptions.
#ifndef JSON_USE_EXCEPTION
#define JSON_USE_EXCEPTION 1
#endif
// Temporary, tracked for removal with issue #982.
#ifndef JSON_USE_NULLREF
#define JSON_USE_NULLREF 1
#endif
/// If defined, indicates that the source file is amalgamated
/// to prevent private header inclusion.
/// Remarks: it is automatically defined in the generated amalgamated header.
// #define JSON_IS_AMALGAMATION
// Export macros for DLL visibility
#if defined(JSON_DLL_BUILD)
#if defined(_MSC_VER) || defined(__MINGW32__)
#define JSON_API __declspec(dllexport)
#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
#elif defined(__GNUC__) || defined(__clang__)
#define JSON_API __attribute__((visibility("default")))
#endif // if defined(_MSC_VER)
#elif defined(JSON_DLL)
#if defined(_MSC_VER) || defined(__MINGW32__)
#define JSON_API __declspec(dllimport)
#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
#endif // if defined(_MSC_VER)
#endif // ifdef JSON_DLL_BUILD
#if !defined(JSON_API)
#define JSON_API
#endif
#if defined(_MSC_VER) && _MSC_VER < 1800
#error \
"ERROR: Visual Studio 12 (2013) with _MSC_VER=1800 is the oldest supported compiler with sufficient C++11 capabilities"
#endif
#if defined(_MSC_VER) && _MSC_VER < 1900
// As recommended at
// https://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010
extern JSON_API int msvc_pre1900_c99_snprintf(char* outBuf, size_t size,
const char* format, ...);
#define jsoncpp_snprintf msvc_pre1900_c99_snprintf
#else
#define jsoncpp_snprintf std::snprintf
#endif
// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for
// integer
// Storages, and 64 bits integer support is disabled.
// #define JSON_NO_INT64 1
// JSONCPP_OVERRIDE is maintained for backwards compatibility of external tools.
// C++11 should be used directly in JSONCPP.
#define JSONCPP_OVERRIDE override
#ifdef __clang__
#if __has_extension(attribute_deprecated_with_message)
#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))
#endif
#elif defined(__GNUC__) // not clang (gcc comes later since clang emulates gcc)
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))
#elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
#endif // GNUC version
#elif defined(_MSC_VER) // MSVC (after clang because clang on Windows emulates
// MSVC)
#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
#endif // __clang__ || __GNUC__ || _MSC_VER
#if !defined(JSONCPP_DEPRECATED)
#define JSONCPP_DEPRECATED(message)
#endif // if !defined(JSONCPP_DEPRECATED)
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 6))
#define JSON_USE_INT64_DOUBLE_CONVERSION 1
#endif
#if !defined(JSON_IS_AMALGAMATION)
#include "allocator.h"
#include "version.h"
#endif // if !defined(JSON_IS_AMALGAMATION)
namespace Json {
using Int = int;
using UInt = unsigned int;
#if defined(JSON_NO_INT64)
using LargestInt = int;
using LargestUInt = unsigned int;
#undef JSON_HAS_INT64
#else // if defined(JSON_NO_INT64)
// For Microsoft Visual use specific types as long long is not supported
#if defined(_MSC_VER) // Microsoft Visual Studio
using Int64 = __int64;
using UInt64 = unsigned __int64;
#else // if defined(_MSC_VER) // Other platforms, use long long
using Int64 = int64_t;
using UInt64 = uint64_t;
#endif // if defined(_MSC_VER)
using LargestInt = Int64;
using LargestUInt = UInt64;
#define JSON_HAS_INT64
#endif // if defined(JSON_NO_INT64)
template <typename T>
using Allocator =
typename std::conditional<JSONCPP_USING_SECURE_MEMORY, SecureAllocator<T>,
std::allocator<T>>::type;
using String = std::basic_string<char, std::char_traits<char>, Allocator<char>>;
using IStringStream =
std::basic_istringstream<String::value_type, String::traits_type,
String::allocator_type>;
using OStringStream =
std::basic_ostringstream<String::value_type, String::traits_type,
String::allocator_type>;
using IStream = std::istream;
using OStream = std::ostream;
} // namespace Json
// Legacy names (formerly macros).
using JSONCPP_STRING = Json::String;
using JSONCPP_ISTRINGSTREAM = Json::IStringStream;
using JSONCPP_OSTRINGSTREAM = Json::OStringStream;
using JSONCPP_ISTREAM = Json::IStream;
using JSONCPP_OSTREAM = Json::OStream;
#endif // JSON_CONFIG_H_INCLUDED
// //////////////////////////////////////////////////////////////////////
// End of content of file: include/json/config.h
// //////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: include/json/forwards.h
// //////////////////////////////////////////////////////////////////////
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef JSON_FORWARDS_H_INCLUDED
#define JSON_FORWARDS_H_INCLUDED
#if !defined(JSON_IS_AMALGAMATION)
#include "config.h"
#endif // if !defined(JSON_IS_AMALGAMATION)
namespace Json {
// writer.h
class StreamWriter;
class StreamWriterBuilder;
class Writer;
class FastWriter;
class StyledWriter;
class StyledStreamWriter;
// reader.h
class Reader;
class CharReader;
class CharReaderBuilder;
// json_features.h
class Features;
// value.h
using ArrayIndex = unsigned int;
class StaticString;
class Path;
class PathArgument;
class Value;
class ValueIteratorBase;
class ValueIterator;
class ValueConstIterator;
} // namespace Json
#endif // JSON_FORWARDS_H_INCLUDED
// //////////////////////////////////////////////////////////////////////
// End of content of file: include/json/forwards.h
// //////////////////////////////////////////////////////////////////////
#endif //ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED

File diff suppressed because it is too large Load Diff

View File

@ -23079,6 +23079,13 @@ namespace sol {
return std::move(*this).template tuple_get<T>(idx_seq());
}
template <typename T>
bool is() const {
typedef decltype(get<T>()) U;
optional<U> option = get<optional<U>>();
return option;
}
template <typename T>
decltype(auto) get_or(T&& otherwise) const {
typedef decltype(get<T>()) U;
@ -23195,6 +23202,24 @@ namespace sol {
}
return *this;
}
// added by me
template<typename T>
inline decltype(auto) as() const& {
return get<T>();
}
template<typename T>
inline decltype(auto) as() && {
return get<T>();
}
inline decltype(auto) begin() {
return get<sol::table>().begin();
}
inline decltype(auto) end() {
return get<sol::table>().end();
}
};
template <typename Table, typename Key, typename T>

View File

@ -8,9 +8,9 @@
#include <functional>
namespace uf {
class UF_API Asset : public uf::Entity {
class UF_API Asset : public uf::Component {
protected:
static uf::Entity masterAssetLoader;
static uf::Asset masterAssetLoader;
public:
// URL or file path
void processQueue();
@ -22,7 +22,7 @@ namespace uf {
template<typename T>
std::vector<T>& getContainer() {
return masterAssetLoader.getComponent<std::vector<T>>();
return this->getComponent<std::vector<T>>();
}
template<typename T>
@ -38,28 +38,38 @@ namespace uf {
template<typename T>
T& get( const std::string& url ) {
std::string extension = uf::io::extension( url );
uf::Serializer& map = masterAssetLoader.getComponent<uf::Serializer>();
std::size_t index = map[extension][url].asUInt64();
uf::Serializer& map = this->getComponent<uf::Serializer>();
std::size_t index = map[extension][url].as<size_t>();
// std::size_t index = map[extension][url];
return this->get<T>(index);
}
template<typename T>
T& add( const std::string& url, const T& copy ) {
std::string extension = uf::io::extension( url );
uf::Serializer& map = masterAssetLoader.getComponent<uf::Serializer>();
uf::Serializer& map = this->getComponent<uf::Serializer>();
auto& container = this->getContainer<T>();
if ( !ext::json::isNull( map[extension][url] ) ) return this->get<T>(url);
// sol::optional<std::string> value = map[extension][url];
// if ( !value ) return this->get<T>(url);
if ( !map[extension][url].isNull() ) return this->get<T>(url);
container.push_back( copy );
return container.back();
}
template<typename T>
T& add( const std::string& url, T&& move ) {
std::string extension = uf::io::extension( url );
uf::Serializer& map = masterAssetLoader.getComponent<uf::Serializer>();
uf::Serializer& map = this->getComponent<uf::Serializer>();
auto& container = this->getContainer<T>();
if ( !map[extension][url].isNull() ) return this->get<T>(url);
if ( !ext::json::isNull( map[extension][url] ) ) return this->get<T>(url);
// sol::optional<std::string> value = map[extension][url];
// if ( !value ) return this->get<T>(url);
container.push_back( move );
return container.back();
}

View File

@ -17,10 +17,10 @@ namespace pod {
typedef std::function<void(uf::Object&)> function_t;
type_t type = std::type_index(typeid(pod::Behavior));
function_t initialize;
function_t tick;
function_t render;
function_t destroy;
function_t initialize = function_t();
function_t tick = function_t();
function_t render = function_t();
function_t destroy = function_t();
};
}

View File

@ -1,5 +1,32 @@
#pragma once
#define UF_BEHAVIOR_ENTITY_H( OBJ )\
class UF_API OBJ ## Behavior {\
public:\
static void attach( uf::Entity& );\
static void initialize( uf::Object& );\
static void tick( uf::Object& );\
static void render( uf::Object& );\
static void destroy( uf::Object& );\
};
#define UF_BEHAVIOR_ENTITY_CPP_BEGIN( OBJ )\
void OBJ ## Behavior::attach( uf::Entity& self ) {\
self.addBehavior(pod::Behavior{\
.type = uf::Behaviors::getType<OBJ ## Behavior>(),\
.initialize = OBJ ## Behavior::initialize,\
.tick = OBJ ## Behavior::tick,\
.render = OBJ ## Behavior::render,\
.destroy = OBJ ## Behavior::destroy,\
});\
}
#define UF_BEHAVIOR_ENTITY_CPP_ATTACH( OBJ ) {\
OBJ ## Behavior::attach( *this );\
}
#define UF_BEHAVIOR_ENTITY_CPP_END( OBJ )
/*
#define UF_BEHAVIOR_VIRTUAL 0
#define UF_BEHAVIOR_ENTITY_H( OBJ )\
@ -53,4 +80,5 @@
.destroy = ext::OBJ ## Behavior::destroy,\
});\
}
#define EXT_BEHAVIOR_ENTITY_CPP_END( OBJ )
#define EXT_BEHAVIOR_ENTITY_CPP_END( OBJ )
*/

View File

@ -14,8 +14,10 @@ namespace uf {
friend class EntityBehavior;
public:
typedef std::vector<uf::Entity*> container_t;
protected:
static uf::Entity null;
static bool deleteChildrenOnDestroy;
static bool deleteComponentsOnDestroy;
protected:
static std::size_t uids;
uf::Entity* m_parent = NULL;

View File

@ -3,6 +3,7 @@
#include <uf/config.h>
#include <uf/engine/entity/entity.h>
#include <uf/utils/singletons/pre_main.h>
#include <uf/utils/string/ext.h>
#include <unordered_map>
#include <typeindex>
#include <functional>
@ -48,6 +49,9 @@ namespace uf {
template<typename T> T* alloc();
void UF_API free( uf::Entity* );
uf::Entity* UF_API reuse( size_t );
size_t UF_API collect( uint8_t = 0 );
template<typename T> void registerObject( const std::string& name );
template<typename T> void registerBehavior( const std::string& name );
template<typename T> void registerBinding( const std::string& name );

View File

@ -1,6 +1,48 @@
#pragma once
#define NAMESPACE_CONCAT
#define TOKEN__PASTE(x, y) x ## y
#define TOKEN_PASTE(x, y) TOKEN__PASTE(x, y)
#define UF_NS_GET_LAST(name) uf::string::replace( uf::string::split( #name, "::" ).back(), "<>", "" )
#define UF_OBJECT_REGISTER_CPP( OBJ ) \
namespace {\
static uf::StaticInitialization TOKEN_PASTE(STATIC_INITIALIZATION_, __LINE__)( []{\
uf::instantiator::registerObject<OBJ>( UF_NS_GET_LAST(OBJ) );\
});\
}
#define UF_BEHAVIOR_REGISTER_CPP( BEHAVIOR ) \
namespace {\
static uf::StaticInitialization TOKEN_PASTE(STATIC_INITIALIZATION_, __LINE__)( []{\
uf::instantiator::registerBehavior<BEHAVIOR>( UF_NS_GET_LAST(BEHAVIOR) );\
});\
}
#define UF_BEHAVIOR_REGISTER_AS_OBJECT( BEHAVIOR, OBJ )\
namespace {\
static uf::StaticInitialization TOKEN_PASTE(STATIC_INITIALIZATION_, __LINE__)( []{\
uf::instantiator::registerBinding( UF_NS_GET_LAST(OBJ), UF_NS_GET_LAST(BEHAVIOR) );\
});\
}
#define UF_OBJECT_REGISTER_BEGIN( OBJ )\
namespace {\
static uf::StaticInitialization TOKEN_PASTE(STATIC_INITIALIZATION_, __LINE__)( []{\
std::string name = UF_NS_GET_LAST(OBJ);\
uf::instantiator::registerObject<OBJ>( name );
#define UF_OBJECT_BIND_BEHAVIOR( BEHAVIOR )\
uf::instantiator::registerBinding( name, UF_NS_GET_LAST(BEHAVIOR) );
#define UF_OBJECT_REGISTER_BEHAVIOR( BEHAVIOR )\
uf::instantiator::registerBehavior<BEHAVIOR>( UF_NS_GET_LAST(BEHAVIOR) );\
UF_OBJECT_BIND_BEHAVIOR( BEHAVIOR )
#define UF_OBJECT_REGISTER_END()\
});\
}
/*
#define UF_OBJECT_REGISTER_CPP( OBJ ) \
namespace {\
static uf::StaticInitialization REGISTER_UF_ ## OBJ( []{\
@ -65,3 +107,4 @@ namespace {\
#define EXT_OBJECT_REGISTER_END()\
});\
}
*/

View File

@ -0,0 +1,32 @@
#pragma once
#include <json/json.h>
namespace ext {
namespace json {
inline bool isTable( const Json::Value& v ) { return v.isArray() || v.isObject(); }
inline bool isObject( const Json::Value& v ) { return v.isObject(); }
inline bool isArray( const Json::Value& v ) { return v.isArray(); }
inline bool isNull( const Json::Value& v ) { return v.isNull(); }
/*
inline bool isTable( sol::object v ) { return v.is<sol::table>(); }
inline bool isObject( sol::object v ) { return v.is<sol::table>(); }
inline bool isArray( sol::object v ) { return v.is<sol::table>(); }
inline bool isNull( sol::object v ) { return v == sol::lua_nil; }
template<typename T>
inline bool isTable( T v ) { return v.get_type() == sol::type::table; }
template<typename T>
inline bool isObject( T v ) { return v.get_type() == sol::type::table; }
template<typename T>
inline bool isArray( T v ) { return v.get_type() == sol::type::table; }
template<typename T>
inline bool isNull( T v ) { return v.get_type() == sol::type::nil; }
*/
}
}
#include "json.inl"

View File

View File

@ -2,14 +2,19 @@
#include <uf/config.h>
#define SOL_LUAJIT 1
#define SOL_USING_CXX_LUA_JIT 1
#define SOL_NO_EXCEPTIONS 1
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>
#include <unordered_map>
#include <uf/utils/singletons/pre_main.h>
#include <uf/utils/string/ext.h>
namespace pod {
struct UF_API LuaScript {
std::string filename;
std::string header;
std::string file;
sol::environment env;
};
}
@ -18,13 +23,22 @@ namespace ext {
namespace lua {
extern UF_API sol::state state;
extern UF_API std::string main;
extern UF_API std::unordered_map<std::string, std::string> modules;
extern UF_API std::vector<std::function<void()>>* onInitializationFunctions;
void UF_API initialize();
void UF_API terminate();
void UF_API onInitialization( const std::function<void()>& );
bool UF_API run( const std::string&, bool = true );
pod::LuaScript UF_API script( const std::string& );
bool UF_API run( const pod::LuaScript& );
bool UF_API run( const pod::LuaScript&, bool = true );
sol::table createTable();
std::string sanitize( const std::string& dirty, int index = -1 );
std::optional<std::string> encode( sol::table table );
std::optional<sol::table> decode( const std::string& string );
}
}

View File

@ -1,14 +1,56 @@
#define POD_LUA_REGISTER_USERTYPE_BEGIN(x)\
state.new_usertype<pod::x>(#x,
#define UF_LUA_REGISTER_USERTYPE_BEGIN(x)\
state.new_usertype<uf::x>(#x,
#define EXT_LUA_REGISTER_USERTYPE_BEGIN(x)\
state.new_usertype<ext::x>(#x,
#define UF_NS_GET_LAST(name) uf::string::replace( uf::string::split( #name, "::" ).back(), "<>", "" )
#define POD_LUA_REGISTER_USERTYPE_MEMBER(x, y) #y, &pod::x::y
#define UF_LUA_REGISTER_USERTYPE_MEMBER(x, y) #y, &uf::x::y
#define EXT_LUA_REGISTER_USERTYPE_MEMBER(x, y) #y, &ext::x::y
#define TOKEN__PASTE(x, y) x ## y
#define TOKEN_PASTE(x, y) TOKEN__PASTE(x, y)
#define UF_LUA_REGISTER_USERTYPE_END(x) );
#define POD_LUA_REGISTER_USERTYPE_END(x) UF_LUA_REGISTER_USERTYPE_END(x)
#define EXT_LUA_REGISTER_USERTYPE_END(x) UF_LUA_REGISTER_USERTYPE_END(x)
#define UF_LUA_REGISTER_USERTYPE_BEGIN(type) \
namespace {\
static uf::StaticInitialization TOKEN_PASTE(STATIC_INITIALIZATION_, __LINE__)( []{\
ext::lua::onInitialization( []{\
std::string name = UF_NS_GET_LAST(type);\
auto usertype = ext::lua::state.new_usertype<type>(name);
#define UF_LUA_REGISTER_USERTYPE_DEFINE_RT(k, v) usertype[#k] = v;
#define UF_LUA_REGISTER_USERTYPE_MEMBER_RT(member) usertype[UF_NS_GET_LAST(member)] = &member;
#define UF_LUA_REGISTER_USERTYPE_END() \
});\
});\
}
#define UF_LUA_REGISTER_USERTYPE(type, ...) \
namespace {\
static uf::StaticInitialization TOKEN_PASTE(STATIC_INITIALIZATION_, __LINE__)( []{\
ext::lua::onInitialization( []{\
ext::lua::state.new_usertype<type>(UF_NS_GET_LAST(type), __VA_ARGS__);\
});\
});\
}
#define UF_LUA_REGISTER_USERTYPE_DEFINE(k, v) #k, v
#define UF_LUA_REGISTER_USERTYPE_MEMBER(member) UF_NS_GET_LAST(member), &member
/*
#define UF_NS_LUA_REGISTER_USERTYPE_BEGIN(k, v) {\
std::string name = #v;\
sol::usertype<k::v> usertype = state.new_usertype<k::v>(name);
#define POD_LUA_REGISTER_USERTYPE_BEGIN(x) UF_NS_LUA_REGISTER_USERTYPE_BEGIN(pod, x)
#define UF_LUA_REGISTER_USERTYPE_BEGIN(x) UF_NS_LUA_REGISTER_USERTYPE_BEGIN(uf, x)
#define EXT_LUA_REGISTER_USERTYPE_BEGIN(x) UF_NS_LUA_REGISTER_USERTYPE_BEGIN(ext, x)
#define UF_LUA_REGISTER_USERTYPE_DEFINE(k, v) usertype[#k] = v;
#define POD_LUA_REGISTER_USERTYPE_DEFINE(k, v) UF_LUA_REGISTER_USERTYPE_DEFINE(k, v)
#define EXT_LUA_REGISTER_USERTYPE_DEFINE(k, v) UF_LUA_REGISTER_USERTYPE_DEFINE(k, v)
#define UF_NS_LUA_REGISTER_USERTYPE_MEMBER(ns, x, y) UF_LUA_REGISTER_USERTYPE_DEFINE(y, &ns::x::y)
#define POD_LUA_REGISTER_USERTYPE_MEMBER(x, y) UF_NS_LUA_REGISTER_USERTYPE_MEMBER(pod, x, y)
#define UF_LUA_REGISTER_USERTYPE_MEMBER(x, y) UF_NS_LUA_REGISTER_USERTYPE_MEMBER(uf, x, y)
#define EXT_LUA_REGISTER_USERTYPE_MEMBER(x, y) UF_NS_LUA_REGISTER_USERTYPE_MEMBER(ext, x, y)
#define UF_LUA_REGISTER_USERTYPE_END() }
#define POD_LUA_REGISTER_USERTYPE_END() UF_LUA_REGISTER_USERTYPE_END()
#define EXT_LUA_REGISTER_USERTYPE_END() UF_LUA_REGISTER_USERTYPE_END()
*/

View File

@ -12,6 +12,8 @@
#include <uf/utils/math/vector.h>
#define AL_CHECK_ERROR(...) __VA_ARGS__; ext::oal.checkError(__FUNCTION__, __LINE__)
namespace ext {
class UF_API AL {
protected:

View File

@ -20,14 +20,19 @@
#include <fstream>
#include <chrono>
*/
#define VK_DEBUG_MESSAGE(...)\
uf::iostream << "[" << __FUNCTION__ << "@" << __FILE__ ":" << __LINE__ << "] " << __VA_ARGS__ << "\n"
#define VK_CHECK_RESULT(f) \
{ \
VkResult res = (f); \
if (res != VK_SUCCESS) { \
std::cerr << "Fatal : VkResult is \"" << ext::vulkan::errorString( res ) << "\" in " << __FILE__ << " at line " << __LINE__ << std::endl; \
throw std::runtime_error(ext::vulkan::errorString( res )); \
} \
#define VK_VALIDATION_MESSAGE(...)\
if ( ext::vulkan::settings::validation ) VK_DEBUG_MESSAGE(__VA_ARGS__);
#define VK_CHECK_RESULT(f) { \
VkResult res = (f); \
if (res != VK_SUCCESS) { \
std::string errorString = ext::vulkan::errorString( res ); \
VK_DEBUG_MESSAGE(errorString); \
throw std::runtime_error(errorString); \
} \
}
#define VK_FLAGS_NONE 0

View File

@ -3,6 +3,8 @@
#include <uf/ext/vulkan.h>
#include <vector>
#define VK_DEFAULT_STAGE_BUFFERS 0
namespace ext {
namespace vulkan {
struct Device;
@ -66,15 +68,15 @@ namespace ext {
void initialize( Device& device );
void destroy();
//
size_t initializeBuffer( void* data, VkDeviceSize length, VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, bool stage = true );
template<typename T> inline size_t initializeBuffer( T data, VkDeviceSize length, VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, bool stage = true ) { return initializeBuffer( (void*) &data, length, usageFlags, memoryPropertyFlags, stage ); }
template<typename T> inline size_t initializeBuffer( T data, VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, bool stage = true ) { return initializeBuffer( (void*) &data, static_cast<VkDeviceSize>(sizeof(T)), usageFlags, memoryPropertyFlags, stage ); }
size_t initializeBuffer( void* data, VkDeviceSize length, VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, bool stage = VK_DEFAULT_STAGE_BUFFERS );
template<typename T> inline size_t initializeBuffer( T data, VkDeviceSize length, VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, bool stage = VK_DEFAULT_STAGE_BUFFERS ) { return initializeBuffer( (void*) &data, length, usageFlags, memoryPropertyFlags, stage ); }
template<typename T> inline size_t initializeBuffer( T data, VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, bool stage = VK_DEFAULT_STAGE_BUFFERS ) { return initializeBuffer( (void*) &data, static_cast<VkDeviceSize>(sizeof(T)), usageFlags, memoryPropertyFlags, stage ); }
void updateBuffer( void* data, VkDeviceSize length, size_t index = 0, bool stage = true );
void updateBuffer( void* data, VkDeviceSize length, Buffer& buffer, bool stage = true );
template<typename T> inline void updateBuffer( T data, VkDeviceSize length, size_t index = 0, bool stage = true ) { return updateBuffer( (void*) &data, length, index, stage ); }
template<typename T> inline void updateBuffer( T data, size_t index = 0, bool stage = true ) { return updateBuffer( (void*) &data, static_cast<VkDeviceSize>(sizeof(T)), index, stage ); }
template<typename T> inline void updateBuffer( T data, VkDeviceSize length, Buffer& buffer, bool stage = true ) { return updateBuffer( (void*) &data, length, buffer, stage ); }
void updateBuffer( void* data, VkDeviceSize length, size_t index = 0, bool stage = VK_DEFAULT_STAGE_BUFFERS );
void updateBuffer( void* data, VkDeviceSize length, Buffer& buffer, bool stage = VK_DEFAULT_STAGE_BUFFERS );
template<typename T> inline void updateBuffer( T data, VkDeviceSize length, size_t index = 0, bool stage = VK_DEFAULT_STAGE_BUFFERS ) { return updateBuffer( (void*) &data, length, index, stage ); }
template<typename T> inline void updateBuffer( T data, size_t index = 0, bool stage = VK_DEFAULT_STAGE_BUFFERS ) { return updateBuffer( (void*) &data, static_cast<VkDeviceSize>(sizeof(T)), index, stage ); }
template<typename T> inline void updateBuffer( T data, VkDeviceSize length, Buffer& buffer, bool stage = VK_DEFAULT_STAGE_BUFFERS ) { return updateBuffer( (void*) &data, length, buffer, stage ); }
};
}
}

View File

@ -97,7 +97,7 @@ namespace ext {
void destroy();
template<typename T, typename U>
void initializeGeometry( uf::BaseMesh<T, U>& mesh, bool = false );
void initializeGeometry( uf::BaseMesh<T, U>& mesh, bool stage = VK_DEFAULT_STAGE_BUFFERS );
bool hasPipeline( GraphicDescriptor& descriptor );
void initializePipeline();

View File

@ -20,6 +20,7 @@ namespace uf {
ext::al::Buffer m_buffer;
float m_duration;
public:
static bool mute;
/*
Audio( const std::string& = "" );
Audio( Audio&& );
@ -60,6 +61,7 @@ namespace uf {
protected:
uf::SoundEmitter::container_t m_container;
public:
~SoundEmitter();
uf::Audio& add( const std::string& );
uf::Audio& add( const uf::Audio& );
uf::Audio& get( const std::string& );

View File

@ -48,6 +48,8 @@ namespace uf {
template<typename T> T& addComponent( const T& = T() );
template<typename T> void deleteComponent();
void destroyComponents();
};
}

View File

@ -95,9 +95,9 @@ namespace uf {
bool isAliasToReadable( const Readable::alias_t::name_t& name ) const; // Is there an alias bound to a readable hook?
bool isAliasToOptimal( const Optimal::alias_t::name_t& name ) const; // Is there an alias bound to an optimal hook?
void call( const Readable::name_t& name );
std::vector<Readable::return_t> call( const Readable::name_t& name );
std::vector<Readable::return_t> call( const Readable::name_t& name, const Readable::argument_t& argument );
void call( const Optimal::name_t& name, const Optimal::argument_t& argument );
std::vector<Optimal::return_t> call( const Optimal::name_t& name, const Optimal::argument_t& argument );
};
class UF_API Hooks {
public:

View File

@ -128,9 +128,11 @@ namespace pod {
// POD vector accessing/manipulation
namespace uf {
namespace vector {
template<typename T> pod::Vector1t<T> /*UF_API*/ create( T x );
template<typename T> pod::Vector2t<T> /*UF_API*/ create( T x, T y );
template<typename T> pod::Vector3t<T> /*UF_API*/ create( T x, T y, T z );
template<typename T> pod::Vector4t<T> /*UF_API*/ create( T x, T y, T z, T w );
template<typename T, size_t N> pod::Vector<T, N> /*UF_API*/ copy( const pod::Vector<T, N>& = {});
// Equality checking
template<typename T> std::size_t /*UF_API*/ compareTo( const T& left, const T& right ); // Equality check between two vectors (less than)
template<typename T> bool /*UF_API*/ equals( const T& left, const T& right ); // Equality check between two vectors (equals)

View File

@ -10,6 +10,8 @@ template<typename T>
pod::Vector3t<T> /*UF_API*/ uf::vector::create( T x, T y, T z ) { pod::Vector3t<T> vec; vec.x = x, vec.y = y, vec.z = z; return vec; }
template<typename T>
pod::Vector4t<T> /*UF_API*/ uf::vector::create( T x, T y, T z, T w ) { pod::Vector4t<T> vec; vec.x = x, vec.y = y, vec.z = z, vec.w = w; return vec; }
template<typename T, size_t N>
pod::Vector<T, N> /*UF_API*/ uf::vector::copy( const pod::Vector<T, N>& v ) { return v; }
// Equality checking
template<typename T> // Equality check between two vectors (less than)
std::size_t /*UF_API*/ uf::vector::compareTo( const T& left, const T& right ) {

View File

@ -1,35 +1,38 @@
#pragma once
#include <uf/config.h>
#include <json/json.h>
#include <uf/utils/userdata/userdata.h>
#include <uf/ext/lua/lua.h>
#include <uf/ext/json/json.h>
#include <string>
#include <type_traits>
#include <uf/utils/userdata/userdata.h>
namespace uf {
// class UF_API Serializer : public sol::table {
class UF_API Serializer : public Json::Value {
public:
typedef std::string output_t;
typedef std::string input_t;
protected:
public:
Serializer( const std::string& str = "" );
Serializer( const Json::Value& );
Serializer( const sol::table& );
Serializer::output_t serialize() const;
Serializer::output_t serialize( bool pretty = false ) const;
void deserialize( const std::string& );
// serializeable
template<typename T>
static bool serializeable() {
// return std::is_pod<T>::value;
return std::is_standard_layout<T>::value && std::is_trivial<T>::value;
return std::is_standard_layout<T>::value && std::is_trivial<T>::value; // std::is_pod<T>::value;
}
template<typename T>
static bool serializeable( const T& input ) {
return serializeable<T>();
}
// serialize to base64
template<typename T>
static uf::Serializer toBase64( const T& input ) {
@ -47,13 +50,13 @@ namespace uf {
// ensure this is a safe type to serialize
if ( !serializeable(input) ) return T();
// ensure it's "proper"
if ( !input["base64"].isString() ) return T();
pod::Userdata* userdata = uf::userdata::fromBase64(input["base64"].asString());
if ( !input["base64"].is<std::string>() ) return T();
pod::Userdata* userdata = uf::userdata::fromBase64(input["base64"].as<std::string>());
T res = uf::userdata::get<T>( userdata );
uf::userdata::destroy( userdata );
return res;
}
bool readFromFile( const std::string& from );
bool writeToFile( const std::string& to ) const;
@ -63,8 +66,11 @@ namespace uf {
operator Serializer::output_t() const;
uf::Serializer& operator=( const std::string& str );
uf::Serializer& operator=( const Json::Value& json );
uf::Serializer& operator=( const sol::table& json );
uf::Serializer& operator<<( const std::string& str );
uf::Serializer& operator>>( std::string& str );
const uf::Serializer& operator>>( std::string& str ) const;
};
typedef Serializer Metadata;
}

View File

@ -40,6 +40,8 @@ namespace uf {
pod::Userdata* UF_API create( uf::MemoryPool&, std::size_t len, void* data = NULL );
template<typename T> pod::Userdata* create( uf::MemoryPool&, const T& data = T() );
void UF_API destroy( uf::MemoryPool&, pod::Userdata* userdata );
size_t UF_API size( size_t size, size_t padding = 0 );
}
}

View File

@ -8,20 +8,22 @@ pod::Userdata* uf::userdata::create( const T& data ) {
template<typename T>
pod::Userdata* uf::userdata::create( uf::MemoryPool& requestedMemoryPool, const T& data ) {
// uf::MemoryPool& memoryPool = uf::MemoryPool::global.size() > 0 ? uf::MemoryPool::global : requestedMemoryPool;
size_t len = sizeof(data);
size_t requestedLen = size( len );
#if UF_MEMORYPOOL_INVALID_MALLOC
uf::MemoryPool& memoryPool = requestedMemoryPool.size() > 0 ? requestedMemoryPool : uf::MemoryPool::global;
pod::Userdata* userdata = (pod::Userdata*) memoryPool.alloc( NULL, sizeof(pod::Userdata) + sizeof(data) );
pod::Userdata* userdata = (pod::Userdata*) memoryPool.alloc( NULL, requestedLen );
#else
uf::MemoryPool* memoryPool = NULL;
if ( requestedMemoryPool.size() > 0 ) memoryPool = &requestedMemoryPool;
else if ( uf::MemoryPool::global.size() > 0 ) memoryPool = &uf::MemoryPool::global;
pod::Userdata* userdata = NULL;
if ( memoryPool )
userdata = (pod::Userdata*) memoryPool->alloc( NULL, sizeof(pod::Userdata) + sizeof(data) );
userdata = (pod::Userdata*) memoryPool->alloc( NULL, requestedLen );
else
userdata = (pod::Userdata*) operator new( sizeof(pod::Userdata) + sizeof(data) ); // allocate data for the userdata struct, and then some }
userdata = (pod::Userdata*) operator new( requestedLen ); // allocate data for the userdata struct, and then some }
#endif
userdata->len = sizeof(data);
userdata->len = len;
union {
uint8_t* from;
T* to;

View File

@ -43,12 +43,12 @@ namespace {
std::string callback;
std::string type;
};
std::queue<Job> jobs;
}
uf::Entity uf::Asset::masterAssetLoader;
uf::Asset uf::Asset::masterAssetLoader;
void uf::Asset::processQueue() {
auto& jobs = this->getComponent<std::queue<Job>>();
mutex.lock();
while ( !jobs.empty() ) {
auto job = jobs.front();
@ -70,11 +70,13 @@ void uf::Asset::processQueue() {
}
void uf::Asset::cache( const std::string& uri, const std::string& callback ) {
mutex.lock();
auto& jobs = this->getComponent<std::queue<Job>>();
jobs.push({ uri, callback, "cache" });
mutex.unlock();
}
void uf::Asset::load( const std::string& uri, const std::string& callback ) {
mutex.lock();
auto& jobs = this->getComponent<std::queue<Job>>();
jobs.push({ uri, callback, "load" });
mutex.unlock();
}
@ -114,14 +116,16 @@ std::string uf::Asset::load( const std::string& uri ) {
}
#define UF_ASSET_REGISTER(type)\
auto& container = this->getContainer<type>();\
if ( !map[extension][uri].isNull() ) return filename;\
if ( !map[extension][filename].isNull() ) return filename;\
if ( !ext::json::isNull( map[extension][uri] ) ) return filename;\
if ( !ext::json::isNull( map[extension][filename] ) ) return filename;\
map[extension][uri] = container.size();\
map[extension][filename] = container.size();\
type& asset = container.emplace_back();
// auto& scene = uf::scene::getCurrentScene();
// auto& masterAssetLoader = scene.getComponent<uf::Asset>();
auto& map = this->getComponent<uf::Serializer>();
// deduce PNG, load as texture
auto& map = masterAssetLoader.getComponent<uf::Serializer>();
if ( extension == "png" ) {
UF_ASSET_REGISTER(uf::Image)
asset.open(filename);
@ -143,7 +147,7 @@ std::string uf::Asset::load( const std::string& uri ) {
auto& metadata = this->getComponent<uf::Serializer>();
#define LOAD_FLAG(name)\
if ( metadata[uri]["flags"][#name].asBool() )\
if ( metadata[uri]["flags"][#name].as<bool>() )\
LOAD_FLAGS |= ext::gltf::LoadMode::name;
LOAD_FLAG(GENERATE_NORMALS); // 0x1 << 0;
@ -164,12 +168,14 @@ std::string uf::Asset::load( const std::string& uri ) {
}
std::string uf::Asset::getOriginal( const std::string& uri ) {
std::string extension = uf::io::extension( uri );
auto& map = masterAssetLoader.getComponent<uf::Serializer>();
if ( map[extension][uri].isNull() ) return uri;
std::size_t index = map[extension][uri].asUInt64();
// auto& scene = uf::scene::getCurrentScene();
// auto& masterAssetLoader = scene.getComponent<uf::Asset>();
auto& map = this->getComponent<uf::Serializer>();
if ( ext::json::isNull( map[extension][uri] ) ) return uri;
std::size_t index = map[extension][uri].as<size_t>();
for ( auto it = map[extension].begin(); it != map[extension].end(); ++it ) {
std::string key = it.key().asString();
std::size_t i = it->asUInt64();
std::string key = it.key().as<std::string>();
std::size_t i = it->as<size_t>();
if ( index == i && key != uri ) return key;
}
return uri;

View File

@ -24,6 +24,8 @@ void uf::Behaviors::removeBehavior( const pod::Behavior& behavior ) {
if ( it != this->m_behaviors.end() ) this->m_behaviors.erase(it);
}
#define FUNCTION_AS_VARIABLE(x) x
#define UF_BEHAVIOR_POLYFILL(f)\
uf::Object& self = *((uf::Object*) this);\
bool headLoopChildren = true;\
@ -31,12 +33,12 @@ void uf::Behaviors::removeBehavior( const pod::Behavior& behavior ) {
bool multithreading = false;\
if ( this->hasComponent<uf::Serializer>() ) {\
auto& metadata = this->getComponent<uf::Serializer>();\
if ( !metadata["system"]["behavior"][#f]["head loop children"].isNull() )\
headLoopChildren = metadata["system"]["behavior"][#f]["head loop children"].asBool();\
if ( !metadata["system"]["behavior"][#f]["forward iteration"].isNull() )\
forwardIteration = metadata["system"]["behavior"][#f]["forward iteration"].asBool();\
if ( !metadata["system"]["behavior"][#f]["multithreading"].isNull() )\
multithreading = metadata["system"]["behavior"][#f]["multithreading"].asBool();\
if ( !ext::json::isNull( metadata["system"]["behavior"][#f]["head loop children"] ) )\
headLoopChildren = metadata["system"]["behavior"][#f]["head loop children"].as<bool>();\
if ( !ext::json::isNull( metadata["system"]["behavior"][#f]["forward iteration"] ) )\
forwardIteration = metadata["system"]["behavior"][#f]["forward iteration"].as<bool>();\
if ( !ext::json::isNull( metadata["system"]["behavior"][#f]["multithreading"] ) )\
multithreading = metadata["system"]["behavior"][#f]["multithreading"].as<bool>();\
}\
auto function = [&]() -> int {\
if ( headLoopChildren ) {\
@ -48,16 +50,18 @@ void uf::Behaviors::removeBehavior( const pod::Behavior& behavior ) {
it->f(self);\
} else {\
if ( forwardIteration ) {\
for ( auto it = this->m_behaviors.begin() + 1; it != this->m_behaviors.end(); ++it )\
auto it = this->m_behaviors.begin();\
for ( ++it; it != this->m_behaviors.end(); ++it )\
it->f(self);\
if ( (it = this->m_behaviors.begin()) != this->m_behaviors.end() ) {\
it->f(self);\
if ( this->m_behaviors.begin() != this->m_behaviors.end() ) {\
this->m_behaviors.begin()->f(self);\
}\
} else {\
for ( auto it = this->m_behaviors.rbegin() + 1; it != this->m_behaviors.rend(); ++it )\
auto it = this->m_behaviors.rbegin();\
for ( ++it; it != this->m_behaviors.rend(); ++it )\
it->f(self);\
if ( (it = this->m_behaviors.rbegin()) != this->m_behaviors.rend() ) {\
it->f(self);\
if ( this->m_behaviors.rbegin() != this->m_behaviors.rend() ) {\
this->m_behaviors.rbegin()->f(self);\
}\
}\
}\
@ -66,24 +70,25 @@ void uf::Behaviors::removeBehavior( const pod::Behavior& behavior ) {
if ( multithreading ) uf::thread::add( uf::thread::fetchWorker(), function, true ); else function();
#define UF_BEHAVIOR_POLYFILL_FAST(f)\
if ( this->m_behaviors.empty() ) return;\
uf::Object& self = *((uf::Object*) this);\
bool headLoopChildren = true;\
bool forwardIteration = true;\
bool multithreading = false;\
if ( this->hasComponent<uf::Serializer>() ) {\
auto& metadata = this->getComponent<uf::Serializer>();\
if ( !metadata["system"]["behavior"][#f]["head loop children"].isNull() )\
headLoopChildren = metadata["system"]["behavior"][#f]["head loop children"].asBool();\
if ( !metadata["system"]["behavior"][#f]["forward iteration"].isNull() )\
forwardIteration = metadata["system"]["behavior"][#f]["forward iteration"].asBool();\
if ( !metadata["system"]["behavior"][#f]["multithreading"].isNull() )\
multithreading = metadata["system"]["behavior"][#f]["multithreading"].asBool();\
if ( !ext::json::isNull( metadata["system"]["behavior"][#f]["head loop children"] ) )\
headLoopChildren = metadata["system"]["behavior"][#f]["head loop children"].as<bool>();\
if ( !ext::json::isNull( metadata["system"]["behavior"][#f]["forward iteration"] ) )\
forwardIteration = metadata["system"]["behavior"][#f]["forward iteration"].as<bool>();\
if ( !ext::json::isNull( metadata["system"]["behavior"][#f]["multithreading"] ) )\
multithreading = metadata["system"]["behavior"][#f]["multithreading"].as<bool>();\
}\
if ( headLoopChildren ) {\
if ( forwardIteration ) {\
auto it = this->m_behaviors.begin();\
if ( it != this->m_behaviors.end() ) {\
this->m_behaviors.begin()->f(self);\
it->f(self);\
}\
for ( ++it; it != this->m_behaviors.end(); ++it ) {\
auto function = [&]() -> int {\
@ -95,7 +100,7 @@ void uf::Behaviors::removeBehavior( const pod::Behavior& behavior ) {
} else {\
auto it = this->m_behaviors.rbegin();\
if ( it != this->m_behaviors.rend() ) {\
this->m_behaviors.rbegin()->f(self);\
it->f(self);\
}\
for ( ++it; it != this->m_behaviors.rend(); ++it ) {\
auto function = [&]() -> int {\
@ -107,26 +112,28 @@ void uf::Behaviors::removeBehavior( const pod::Behavior& behavior ) {
}\
} else {\
if ( forwardIteration ) {\
for ( auto it = this->m_behaviors.begin() + 1; it != this->m_behaviors.end(); ++it ) {\
auto it = this->m_behaviors.begin();\
for ( ++it; it != this->m_behaviors.end(); ++it ) {\
auto function = [&]() -> int {\
it->f(self);\
return 0;\
};\
if ( multithreading ) uf::thread::add( uf::thread::fetchWorker(), function, true ); else function();\
}\
if ( this->m_behaviors.begin() != this->m_behaviors.end() ) {\
this->m_behaviors.begin()->f(self);\
if ( (it = this->m_behaviors.begin()) != this->m_behaviors.end() ) {\
it->f(self);\
}\
} else {\
for ( auto it = this->m_behaviors.rbegin() + 1; it != this->m_behaviors.rend(); ++it ) {\
auto it = this->m_behaviors.rbegin();\
for ( ++it; it != this->m_behaviors.rend(); ++it ) {\
auto function = [&]() -> int {\
it->f(self);\
return 0;\
};\
if ( multithreading ) uf::thread::add( uf::thread::fetchWorker(), function, true ); else function();\
}\
if ( this->m_behaviors.rbegin() != this->m_behaviors.rend() ) {\
this->m_behaviors.rbegin()->f(self);\
if ( (it = this->m_behaviors.rbegin()) != this->m_behaviors.rend() ) {\
it->f(self);\
}\
}\
}

View File

@ -1,6 +1,7 @@
#include <uf/engine/entity/entity.h>
UF_BEHAVIOR_ENTITY_CPP_BEGIN(Entity)
UF_BEHAVIOR_ENTITY_CPP_BEGIN(uf::Entity)
uf::Entity::Entity() UF_BEHAVIOR_ENTITY_CPP_ATTACH(uf::Entity)
#define this ((uf::Entity*) &self)
void uf::EntityBehavior::initialize( uf::Object& self ) {
if ( this->m_uid == 0 )
@ -25,11 +26,14 @@ void uf::EntityBehavior::destroy( uf::Object& self ) {
if ( !kv ) continue;
if ( kv->getUid() == 0 ) continue;
kv->destroy();
delete kv;
if ( uf::Entity::deleteChildrenOnDestroy ) delete kv;
}
this->m_children.clear();
this->m_uid = 0;
if ( this->hasParent() ) this->getParent().removeChild(*this);
if ( this->hasParent() )
this->getParent().removeChild(*this);
if ( uf::Entity::deleteComponentsOnDestroy ) this->destroyComponents();
}
#undef this
UF_BEHAVIOR_ENTITY_CPP_END(Entity)

View File

@ -5,6 +5,8 @@
uf::Entity uf::Entity::null;
std::size_t uf::Entity::uids = 0;
uf::MemoryPool uf::Entity::memoryPool;
bool uf::Entity::deleteChildrenOnDestroy = false;
bool uf::Entity::deleteComponentsOnDestroy = false;
uf::Entity::~Entity(){
this->destroy();
}

View File

@ -1,11 +1,51 @@
#include <uf/engine/instantiator/instantiator.h>
#include <uf/engine/object/object.h>
#include <uf/engine/scene/scene.h>
#include <assert.h>
pod::NamedTypes<pod::Instantiator>* uf::instantiator::objects = NULL;
pod::NamedTypes<pod::Behavior>* uf::instantiator::behaviors = NULL;
uf::Entity* uf::instantiator::reuse( size_t size ) {
uf::Entity* laxed = NULL;
auto& allocations = uf::Entity::memoryPool.allocations();
for ( auto& allocation : allocations ) {
uf::Entity* e = (uf::Entity*) allocation.pointer;
// no scenes
if ( std::find( uf::scene::scenes.begin(), uf::scene::scenes.end(), (uf::Scene*) e ) != uf::scene::scenes.end() ) continue;
// only orphaned
if ( e->hasParent() ) continue;
// only destroyed entities
if ( e->getName() == "Entity" || e->getUid() > 0 ) continue;
if ( allocation.size == size ) return e;
if ( allocation.size > size ) laxed = e;
}
return laxed;
}
size_t uf::instantiator::collect( uint8_t level ) {
size_t collected = 0;
auto& allocations = uf::Entity::memoryPool.allocations();
auto& scene = uf::scene::getCurrentScene();
for ( auto& allocation : allocations ) {
uf::Entity* e = (uf::Entity*) allocation.pointer;
// no scenes
// if ( std::find( uf::scene::scenes.begin(), uf::scene::scenes.end(), (uf::Scene*) e ) != uf::scene::scenes.end() ) continue;
// not current scene
if ( e->getUid() == scene.getUid() ) continue;
// only orphaned
if ( e->hasParent() ) continue;
// uninitialized
if ( e->getName() == "Entity" && e->getUid() == 0 ) continue;
uf::iostream << "Found orphan: " << e->getName() << ": " << e->getUid() << "\n";
uf::instantiator::free( e );
++collected;
}
return collected;
}
uf::Entity* uf::instantiator::alloc( size_t size ) {
// auto* reused = reuse( size ); if ( reused ) return reused;
#if UF_MEMORYPOOL_INVALID_MALLOC
uf::MemoryPool& memoryPool = uf::Entity::memoryPool.size() > 0 ? uf::Entity::memoryPool : uf::MemoryPool::global;
return (uf::Entity*) memoryPool.alloc( NULL, size );
@ -22,6 +62,9 @@ uf::Entity* uf::instantiator::alloc( size_t size ) {
#endif
}
void uf::instantiator::free( uf::Entity* pointer ) {
if ( !pointer ) return;
if ( pointer->getUid() > 0 ) pointer->destroy();
#if UF_MEMORYPOOL_INVALID_FREE
uf::MemoryPool& memoryPool = uf::Entity::memoryPool.size() > 0 ? uf::Entity::memoryPool : uf::MemoryPool::global;
memoryPool.free( pointer );

View File

@ -10,28 +10,17 @@
#include <uf/utils/renderer/renderer.h>
#include <uf/ext/gltf/gltf.h>
UF_BEHAVIOR_ENTITY_CPP_BEGIN(Object)
UF_BEHAVIOR_ENTITY_CPP_BEGIN(uf::Object)
#define this (&self)
void uf::ObjectBehavior::initialize( uf::Object& self ) {
auto& scene = uf::scene::getCurrentScene();
auto& assetLoader = scene.getComponent<uf::Asset>();
auto& metadata = this->getComponent<uf::Serializer>();
/*
size_t target = 0;
for ( int i = 0; i < metadata["system"]["assets"].size(); ++i ) {
std::string filename = metadata["system"]["assets"][i].isObject() ? metadata["system"]["assets"][i]["filename"].asString() : metadata["system"]["assets"][i].asString();
if ( uf::io::extension(filename) != "json" ) ++target;
}
if ( target > 0 ) {
metadata["system"]["load"]["progress"] = 0;
metadata["system"]["load"]["total"] = target;
}
*/
//
{
size_t assets = metadata["system"]["assets"].size();
if ( metadata["system"]["load"]["ignore"].isBool() ) assets = 0;
if ( metadata["system"]["load"]["ignore"].is<bool>() ) assets = 0;
metadata["system"]["load"]["progress"] = 0;
metadata["system"]["load"]["total"] = assets;
if ( assets == 0 ) {
@ -42,11 +31,27 @@ void uf::ObjectBehavior::initialize( uf::Object& self ) {
}
}
this->addHook( "object:UpdateMetadata.%UID%", [&](const std::string& event)->std::string{
uf::Serializer json = event;
metadata.merge(json, true);
return "true";
/*
std::string keyString = match[1].str();
std::string valueString = match[2].str();
auto keys = uf::string::split(keyString, ".");
uf::Serializer value; value.deserialize(valueString);
Json::Value* traversal = &::config;
for ( auto& key : keys ) {
traversal = &((*traversal)[key]);
}
*traversal = value;
*/
});
this->addHook( "asset:QueueLoad.%UID%", [&](const std::string& event)->std::string{
uf::Serializer json = event;
std::string filename = json["filename"].asString();
std::string filename = json["filename"].as<std::string>();
std::string callback = this->formatHookName("asset:FinishedLoad.%UID%");
if ( json["single threaded"].asBool() ) {
if ( json["single threaded"].as<bool>() ) {
assetLoader.load( filename );
this->queueHook( callback, event );
} else {
@ -62,8 +67,8 @@ void uf::ObjectBehavior::initialize( uf::Object& self ) {
});
this->addHook( "asset:Load.%UID%", [&](const std::string& event)->std::string{
uf::Serializer json = event;
std::string filename = json["filename"].asString();
bool initialize = json["initialize"].isNull() ? true : json["initialize"].asBool();
std::string filename = json["filename"].as<std::string>();
bool initialize = ext::json::isNull( json["initialize"] ) ? true : json["initialize"].as<bool>();
if ( uf::io::extension(filename) != "json" ) return "false";
@ -84,8 +89,8 @@ void uf::ObjectBehavior::initialize( uf::Object& self ) {
int portion = 1;
auto& total = metadata["system"]["load"]["total"];
auto& progress = metadata["system"]["load"]["progress"];
progress = progress.asInt() + portion;
if ( progress.asInt() == total.asInt() ) {
progress = progress.as<int>() + portion;
if ( progress.as<int>() == total.as<int>() ) {
auto& parent = this->getParent().as<uf::Object>();
uf::Serializer payload;
@ -93,13 +98,13 @@ void uf::ObjectBehavior::initialize( uf::Object& self ) {
parent.callHook("asset:Parsed.%UID%", payload);
}
/*
float portion = 1.0f / metadata["system"]["load"]["total"].asFloat();
float portion = 1.0f / metadata["system"]["load"]["total"].as<float>();
auto& progress = metadata["system"]["load"]["progress"];
progress = progress.asFloat() + portion;
progress = progress.as<float>() + portion;
*/
/*
if ( metadata["system"]["loaded"].asBool() ) return "false";
if ( progress.asFloat() >= 1.0f ) {
if ( metadata["system"]["loaded"].as<bool>() ) return "false";
if ( progress.as<float>() >= 1.0f ) {
this->queueHook("system:Load.Finished.%UID%");
}
*/
@ -109,9 +114,9 @@ void uf::ObjectBehavior::initialize( uf::Object& self ) {
void uf::ObjectBehavior::destroy( uf::Object& self ) {
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
for( Json::Value::iterator it = metadata["system"]["hooks"]["alloc"].begin() ; it != metadata["system"]["hooks"]["alloc"].end() ; ++it ) {
std::string name = it.key().asString();
std::string name = it.key().as<std::string>();
for ( size_t i = 0; i < metadata["system"]["hooks"]["alloc"][name].size(); ++i ) {
size_t id = metadata["system"]["hooks"]["alloc"][name][(int) i].asUInt();
size_t id = metadata["system"]["hooks"]["alloc"][name][(int) i].as<size_t>();
uf::hooks.removeHook(name, id);
}
}
@ -125,10 +130,10 @@ void uf::ObjectBehavior::destroy( uf::Object& self ) {
void uf::ObjectBehavior::tick( uf::Object& self ) {
// listen for metadata file changes
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
if ( metadata["system"]["hot reload"]["enabled"].asBool() ) {
size_t mtime = uf::io::mtime( metadata["system"]["source"].asString() );
if ( metadata["system"]["hot reload"]["mtime"].asUInt64() < mtime ) {
std::cout << "File reload detected: " << ": " << metadata["system"]["source"].asString() << ", " << metadata["system"]["hot reload"]["mtime"] << " -> " << mtime << std::endl;
if ( metadata["system"]["hot reload"]["enabled"].as<bool>() ) {
size_t mtime = uf::io::mtime( metadata["system"]["source"].as<std::string>() );
if ( metadata["system"]["hot reload"]["mtime"].as<size_t>() < mtime ) {
std::cout << "File reload detected: " << ": " << metadata["system"]["source"].as<std::string>() << ", " << metadata["system"]["hot reload"]["mtime"] << " -> " << mtime << std::endl;
metadata["system"]["hot reload"]["mtime"] = mtime;
this->reload();
//this->queueHook("metadata:Reload.%UID%");
@ -142,21 +147,21 @@ void uf::ObjectBehavior::tick( uf::Object& self ) {
uf::Serializer newQueue = Json::Value(Json::arrayValue);
for ( auto& member : metadata["system"]["hooks"]["queue"] ) {
uf::Serializer payload = member["payload"];
std::string name = member["name"].asString();
float timeout = member["timeout"].asFloat();
std::string name = member["name"].as<std::string>();
float timeout = member["timeout"].as<float>();
if ( timeout < curTime ) {
this->callHook( name, payload );
} else {
newQueue.append(member);
}
}
if ( metadata.isObject() ) metadata["system"]["hooks"]["queue"] = newQueue;
if ( ext::json::isObject( metadata ) ) metadata["system"]["hooks"]["queue"] = newQueue;
}
}
void uf::ObjectBehavior::render( uf::Object& self ) {
auto& metadata = this->getComponent<uf::Serializer>();
/*
if ( metadata["system"]["type"].isNull() || metadata["system"]["defaults"]["render"].asBool() ) {
if ( ext::json::isNull( metadata["system"]["type"] ) || metadata["system"]["defaults"]["render"].as<bool>() ) {
if ( this->hasComponent<uf::Graphic>() ) {
auto& scene = uf::scene::getCurrentScene();
auto& graphic = this->getComponent<uf::Graphic>();

View File

@ -13,7 +13,7 @@
#include <uf/ext/gltf/gltf.h>
#include <uf/utils/string/hash.h>
UF_BEHAVIOR_REGISTER_CPP(GltfBehavior)
UF_BEHAVIOR_REGISTER_CPP(uf::GltfBehavior)
#define this (&self)
void uf::GltfBehavior::initialize( uf::Object& self ) {
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
@ -21,7 +21,7 @@ void uf::GltfBehavior::initialize( uf::Object& self ) {
// Default load: GLTF model
this->addHook( "asset:Load.%UID%", [&](const std::string& event)->std::string{
uf::Serializer json = event;
std::string filename = json["filename"].asString();
std::string filename = json["filename"].as<std::string>();
if ( uf::io::extension(filename) != "png" ) return "false";
auto& vector = metadata["textures"]["additional"];
vector[vector.size()] = filename;
@ -29,7 +29,7 @@ void uf::GltfBehavior::initialize( uf::Object& self ) {
});
this->addHook( "asset:Load.%UID%", [&](const std::string& event)->std::string{
uf::Serializer json = event;
std::string filename = json["filename"].asString();
std::string filename = json["filename"].as<std::string>();
if ( uf::io::extension(filename) != "gltf" && uf::io::extension(filename) != "glb" ) return "false";
@ -47,21 +47,21 @@ void uf::GltfBehavior::initialize( uf::Object& self ) {
{
std::string filename = "/gltf.stereo.vert.spv";
if ( metadata["system"]["renderer"]["shaders"]["vertex"].isString() )
filename = metadata["system"]["renderer"]["shaders"]["vertex"].asString();
filename = this->grabURI( filename, metadata["system"]["root"].asString() );
if ( metadata["system"]["renderer"]["shaders"]["vertex"].is<std::string>() )
filename = metadata["system"]["renderer"]["shaders"]["vertex"].as<std::string>();
filename = this->grabURI( filename, metadata["system"]["root"].as<std::string>() );
graphic.material.attachShader(filename, VK_SHADER_STAGE_VERTEX_BIT);
}
{
std::string filename = "/gltf.frag.spv";
if ( metadata["system"]["renderer"]["shaders"]["fragment"].isString() )
filename = metadata["system"]["renderer"]["shaders"]["fragment"].asString();
filename = this->grabURI( filename, metadata["system"]["root"].asString() );
if ( metadata["system"]["renderer"]["shaders"]["fragment"].is<std::string>() )
filename = metadata["system"]["renderer"]["shaders"]["fragment"].as<std::string>();
filename = this->grabURI( filename, metadata["system"]["root"].as<std::string>() );
graphic.material.attachShader(filename, VK_SHADER_STAGE_FRAGMENT_BIT);
}
for ( int i = 0; i < metadata["textures"]["additional"].size(); ++i ) {
std::string filename = metadata["textures"]["additional"][i].asString();
std::string filename = metadata["textures"]["additional"][i].as<std::string>();
auto& scene = uf::scene::getCurrentScene();
auto& assetLoader = scene.getComponent<uf::Asset>();
const uf::Image* imagePointer = NULL;
@ -128,16 +128,16 @@ void uf::GltfBehavior::tick( uf::Object& self ) {
mappings[i].blend = 0.0f;
}
for ( auto it = metadata["textures"]["map"].begin(); it != metadata["textures"]["map"].end(); ++it ) {
std::string key = it.key().asString();
std::string key = it.key().as<std::string>();
uint32_t from = std::stoi(key);
uint32_t to = metadata["textures"]["map"][key][0].asUInt();
uint32_t to = metadata["textures"]["map"][key][0].as<size_t>();
float blend = 1.0f;
if ( metadata["textures"]["map"][key][1].asString() == "sin(time)" ) {
if ( metadata["textures"]["map"][key][1].as<std::string>() == "sin(time)" ) {
blend = sin(uf::physics::time::current)*0.5f+0.5f;
} else if ( metadata["textures"]["map"][key][1].asString() == "cos(time)" ) {
} else if ( metadata["textures"]["map"][key][1].as<std::string>() == "cos(time)" ) {
blend = cos(uf::physics::time::current)*0.5f+0.5f;
} else if ( metadata["textures"]["map"][key][1].isNumeric() ) {
blend = metadata["textures"]["map"][key][1].asFloat();
} else if ( metadata["textures"]["map"][key][1].is<double>() ) {
blend = metadata["textures"]["map"][key][1].as<float>();
}
if ( from >= textures || to >= textures ) continue;
mappings[from].target = to;

View File

@ -12,7 +12,7 @@
#include <uf/utils/graphic/mesh.h>
#include <uf/ext/gltf/gltf.h>
UF_BEHAVIOR_REGISTER_CPP(LoadingBehavior)
UF_BEHAVIOR_REGISTER_CPP(uf::LoadingBehavior)
#define this (&self)
void uf::LoadingBehavior::initialize( uf::Object& self ) {
auto& metadata = this->getComponent<uf::Serializer>();
@ -22,9 +22,9 @@ void uf::LoadingBehavior::initialize( uf::Object& self ) {
int portion = 1;
auto& total = metadata["system"]["load"]["total"];
auto& progress = metadata["system"]["load"]["progress"];
if ( json["uid"].isNull() ) return "false";
// progress = progress.asInt() + portion;
if ( progress.asInt() == total.asInt() ) {
if ( ext::json::isNull( json["uid"] ) ) return "false";
// progress = progress.as<int>() + portion;
if ( progress.as<int>() == total.as<int>() ) {
auto& parent = this->getParent().as<uf::Object>();
parent.callHook("asset:Parsed.%UID%");
}
@ -81,16 +81,16 @@ void uf::LoadingBehavior::destroy( uf::Object& self ) {
}
void uf::LoadingBehavior::tick( uf::Object& self ) {
auto& metadata = this->getComponent<uf::Serializer>();
if ( metadata["system"]["loaded"].asBool() ) return;
if ( metadata["system"]["loaded"].as<bool>() ) return;
size_t loading = 0;
size_t loaded = 1;
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
if ( !entity || entity->getUid() == 0 || !entity->hasComponent<uf::Serializer>() ) return;
auto& metadata = entity->getComponent<uf::Serializer>();
if ( metadata["system"]["load"]["ignore"].isBool() ) return;
if ( metadata["system"]["load"].isNull() ) return;
if ( metadata["system"]["load"]["ignore"].is<bool>() ) return;
if ( ext::json::isNull( metadata["system"]["load"] ) ) return;
++loading;
if ( metadata["system"]["load"]["progress"].asInt() < metadata["system"]["load"]["total"].asInt() ) return;
if ( metadata["system"]["load"]["progress"].as<int>() < metadata["system"]["load"]["total"].as<int>() ) return;
++loaded;
};
this->process(filter);
@ -100,15 +100,15 @@ void uf::LoadingBehavior::tick( uf::Object& self ) {
}
/*
auto& metadata = this->getComponent<uf::Serializer>();
if ( !metadata["system"]["loaded"].asBool() ) {
if ( !metadata["system"]["loaded"].as<bool>() ) {
size_t loading = 0;
size_t loaded = 0;
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
if ( !entity || entity->getUid() == 0 || !entity->hasComponent<uf::Serializer>() ) return;
auto& metadata = entity->getComponent<uf::Serializer>();
if ( metadata["system"]["load"].isNull() ) return;
if ( ext::json::isNull( metadata["system"]["load"] ) ) return;
++loading;
if ( metadata["system"]["load"]["progress"].asFloat() < 1.0f ) return;
if ( metadata["system"]["load"]["progress"].as<float>() < 1.0f ) return;
++loaded;
};
this->process(filter);
@ -117,7 +117,7 @@ void uf::LoadingBehavior::tick( uf::Object& self ) {
this->callHook("system:Load.Finished.%UID%");
}
auto& metadata = this->getComponent<uf::Serializer>();
if ( metadata["system"]["load"]["progress"].asFloat() >= 1.0f ) {
if ( metadata["system"]["load"]["progress"].as<float>() >= 1.0f ) {
this->callHook("system:Load.Finished.%UID%");
}
}

View File

@ -13,12 +13,12 @@
#include <uf/ext/lua/lua.h>
UF_BEHAVIOR_REGISTER_CPP(LuaBehavior)
UF_BEHAVIOR_REGISTER_CPP(uf::LuaBehavior)
#define this (&self)
void uf::LuaBehavior::initialize( uf::Object& self ) {
this->addHook( "asset:Load.%UID%", [&](const std::string& event)->std::string{
uf::Serializer json = event;
std::string filename = json["filename"].asString();
std::string filename = json["filename"].as<std::string>();
if ( uf::io::extension(filename) != "lua" ) return "false";
uf::Scene& scene = uf::scene::getCurrentScene();
@ -27,8 +27,8 @@ void uf::LuaBehavior::initialize( uf::Object& self ) {
try { assetPointer = &assetLoader.get<pod::LuaScript>(filename); } catch ( ... ) {}
if ( !assetPointer ) return "false";
pod::LuaScript script = *assetPointer;
script.header = "local ent = entities.get("+ std::to_string((uint) this->getUid()) +")";
// script.header = "local ent = entities.get("+ std::to_string((uint) this->getUid()) +")";
script.env["ent"] = &this->as<uf::Object>();
ext::lua::run( script );
return "true";

View File

@ -11,7 +11,7 @@
#include <uf/utils/graphic/mesh.h>
#include <uf/ext/gltf/gltf.h>
UF_BEHAVIOR_REGISTER_CPP(RenderBehavior)
UF_BEHAVIOR_REGISTER_CPP(uf::RenderBehavior)
#define this (&self)
void uf::RenderBehavior::initialize( uf::Object& self ) {

View File

@ -14,10 +14,11 @@ namespace {
uf::Object null;
}
UF_OBJECT_REGISTER_BEGIN(Object)
UF_OBJECT_REGISTER_BEHAVIOR(EntityBehavior)
UF_OBJECT_REGISTER_BEHAVIOR(ObjectBehavior)
UF_OBJECT_REGISTER_BEGIN(uf::Object)
UF_OBJECT_REGISTER_BEHAVIOR(uf::EntityBehavior)
UF_OBJECT_REGISTER_BEHAVIOR(uf::ObjectBehavior)
UF_OBJECT_REGISTER_END()
uf::Object::Object() UF_BEHAVIOR_ENTITY_CPP_ATTACH(uf::Object)
void uf::Object::queueHook( const std::string& name, const std::string& payload, double timeout ) {
if ( !uf::Object::timer.running() ) uf::Object::timer.start();
float start = uf::Object::timer.elapsed().asDouble();
@ -29,9 +30,15 @@ void uf::Object::queueHook( const std::string& name, const std::string& payload,
metadata["system"]["hooks"]["queue"].append(queue);
}
std::string uf::Object::formatHookName( const std::string& n ) {
if ( !this ) return n;
size_t uid = this->getUid();
size_t parent = uid;
if ( this->hasParent() ) {
parent = this->getParent().getUid();
}
std::unordered_map<std::string, std::string> formats = {
{"%UID%", std::to_string(this->getUid())},
{"%P-UID%", std::to_string(this->getParent().getUid())},
{"%UID%", std::to_string(uid)},
{"%P-UID%", std::to_string(parent)},
};
std::string name = n;
for ( auto& pair : formats ) {
@ -56,7 +63,7 @@ bool uf::Object::load( const std::string& f, bool inheritRoot ) {
if ( inheritRoot && this->hasParent() ) {
auto& parent = this->getParent<uf::Object>();
uf::Serializer& metadata = parent.getComponent<uf::Serializer>();
root = metadata["system"]["root"].asString();
root = metadata["system"]["root"].as<std::string>();
}
std::string filename = grabURI( f, root );
if ( !json.readFromFile( filename ) ) {
@ -71,10 +78,10 @@ bool uf::Object::load( const std::string& f, bool inheritRoot ) {
bool uf::Object::reload( bool hard ) {
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
if ( !metadata["system"]["source"].isString() ) return false;
if ( !metadata["system"]["source"].is<std::string>() ) return false;
uf::Serializer json;
uf::Serializer payload;
std::string filename = metadata["system"]["source"].asString(); //grabURI( metadata["system"]["source"].asString(), metadata["system"]["root"].asString() ); // uf::io::sanitize(metadata["system"]["source"].asString(), metadata["system"]["root"].asString());
std::string filename = metadata["system"]["source"].as<std::string>(); //grabURI( metadata["system"]["source"].as<std::string>(), metadata["system"]["root"].as<std::string>() ); // uf::io::sanitize(metadata["system"]["source"].as<std::string>(), metadata["system"]["root"].as<std::string>());
if ( !json.readFromFile( filename ) ) {
uf::iostream << "Error @ " << __FILE__ << ":" << __LINE__ << ": failed to open `" + filename + "`" << "\n";
uf::iostream << this << ": " << this->getName() << ": " << this->getUid() << ": " << metadata << "\n";
@ -84,7 +91,7 @@ bool uf::Object::reload( bool hard ) {
payload["old"] = metadata;
for ( auto it = json["metadata"].begin(); it != json["metadata"].end(); ++it ) {
metadata[it.key().asString()] = json["metadata"][it.key().asString()];
metadata[it.key().as<std::string>()] = json["metadata"][it.key().as<std::string>()];
}
payload["new"] = metadata;
std::cout << "Updated metadata for " << this->getName() << ": " << this->getUid() << std::endl;
@ -98,87 +105,87 @@ bool uf::Object::load( const uf::Serializer& _json ) {
uf::Serializer json = _json;
// copy system table to base
for ( auto it = json["system"].begin(); it != json["system"].end(); ++it ) {
std::string key = it.key().asString();
if ( json[key].isNull() )
std::string key = it.key().as<std::string>();
if ( ext::json::isNull( json[key] ) )
json[key] = json["system"][key];
}
json["hot reload"]["enabled"] = json["system"]["hot reload"]["enabled"];
// Basic entity information
{
// Set name
this->m_name = json["name"].isString() ? json["name"].asString() : json["type"].asString();
this->m_name = json["name"].is<std::string>() ? json["name"].as<std::string>() : json["type"].as<std::string>();
}
// Bind behaviors
if ( json["type"].isString() ) {
uf::instantiator::bind( json["type"].asString(), *this );
if ( json["type"].is<std::string>() ) {
uf::instantiator::bind( json["type"].as<std::string>(), *this );
}
if ( json["defaults"]["render"].asBool() ) {
if ( json["defaults"]["render"].as<bool>() ) {
uf::instantiator::bind( "RenderBehavior", *this );
}
if ( json["defaults"]["asset load"].asBool() ) {
if ( json["defaults"]["asset load"].as<bool>() ) {
uf::instantiator::bind( "GltfBehavior", *this );
}
{
uf::Serializer target;
if ( metadata["system"]["behaviors"].isArray() ) {
if ( ext::json::isArray( metadata["system"]["behaviors"] ) ) {
target = metadata["system"]["behaviors"];
} else if ( json["behaviors"].isArray() ) {
} else if ( ext::json::isArray( json["behaviors"] ) ) {
target = json["behaviors"];
}
for ( uint i = 0; i < target.size(); ++i ) {
uf::instantiator::bind( target[i].asString(), *this );
uf::instantiator::bind( target[i].as<std::string>(), *this );
}
}
// Set transform
{
bool load = json["transform"].isObject();
bool load = ext::json::isObject( json["transform"] );
if ( this->hasComponent<pod::Transform<>>() ) load = false;
pod::Transform<>& transform = this->getComponent<pod::Transform<>>();
if ( transform.position.x == 0 && transform.position.y == 0 && transform.position.z == 0 ) {
load = true;
}
if ( load ) {
transform.position.x = json["transform"]["position"][0].asFloat();
transform.position.y = json["transform"]["position"][1].asFloat();
transform.position.z = json["transform"]["position"][2].asFloat();
transform.position.x = json["transform"]["position"][0].as<float>();
transform.position.y = json["transform"]["position"][1].as<float>();
transform.position.z = json["transform"]["position"][2].as<float>();
transform.orientation = uf::quaternion::identity();
if ( json["transform"]["orientation"].isArray() ) {
transform.orientation.x = json["transform"]["orientation"][0].asFloat();
transform.orientation.y = json["transform"]["orientation"][1].asFloat();
transform.orientation.z = json["transform"]["orientation"][2].asFloat();
transform.orientation.w = json["transform"]["orientation"][3].asFloat();
} else if ( json["transform"]["rotation"]["angle"].asFloat() != 0 ) {
if ( ext::json::isArray( json["transform"]["orientation"] ) ) {
transform.orientation.x = json["transform"]["orientation"][0].as<float>();
transform.orientation.y = json["transform"]["orientation"][1].as<float>();
transform.orientation.z = json["transform"]["orientation"][2].as<float>();
transform.orientation.w = json["transform"]["orientation"][3].as<float>();
} else if ( json["transform"]["rotation"]["angle"].as<float>() != 0 ) {
transform.orientation = uf::quaternion::axisAngle( {
json["transform"]["rotation"]["axis"][0].asFloat(),
json["transform"]["rotation"]["axis"][1].asFloat(),
json["transform"]["rotation"]["axis"][2].asFloat()
json["transform"]["rotation"]["axis"][0].as<float>(),
json["transform"]["rotation"]["axis"][1].as<float>(),
json["transform"]["rotation"]["axis"][2].as<float>()
},
json["transform"]["rotation"]["angle"].asFloat()
json["transform"]["rotation"]["angle"].as<float>()
);
}
if ( json["transform"]["scale"].isArray() ) {
transform.scale = uf::vector::create( json["transform"]["scale"][0].asFloat(),json["transform"]["scale"][1].asFloat(),json["transform"]["scale"][2].asFloat() );
if ( ext::json::isArray( json["transform"]["scale"] ) ) {
transform.scale = uf::vector::create( json["transform"]["scale"][0].as<float>(),json["transform"]["scale"][1].as<float>(),json["transform"]["scale"][2].as<float>() );
}
transform = uf::transform::reorient( transform );
}
}
// Set movement
{
if ( json["physics"].isObject() && !this->hasComponent<pod::Physics>() ) {
if ( ext::json::isObject( json["physics"] ) && !this->hasComponent<pod::Physics>() ) {
auto& physics = this->getComponent<pod::Physics>();
if ( json["physics"]["linear"]["velocity"].isArray() )
if ( ext::json::isArray( json["physics"]["linear"]["velocity"] ) )
for ( uint j = 0; j < 3; ++j )
physics.linear.velocity[j] = json["physics"]["linear"]["velocity"][j].asFloat();
if ( json["physics"]["linear"]["acceleration"].isArray() )
physics.linear.velocity[j] = json["physics"]["linear"]["velocity"][j].as<float>();
if ( ext::json::isArray( json["physics"]["linear"]["acceleration"] ) )
for ( uint j = 0; j < 3; ++j )
physics.linear.acceleration[j] = json["physics"]["linear"]["acceleration"][j].asFloat();
physics.linear.acceleration[j] = json["physics"]["linear"]["acceleration"][j].as<float>();
if ( json["physics"]["rotational"]["velocity"].isArray() )
if ( ext::json::isArray( json["physics"]["rotational"]["velocity"] ) )
for ( uint j = 0; j < 4; ++j )
physics.rotational.velocity[j] = json["physics"]["rotational"]["velocity"][j].asFloat();
if ( json["physics"]["rotational"]["acceleration"].isArray() )
physics.rotational.velocity[j] = json["physics"]["rotational"]["velocity"][j].as<float>();
if ( ext::json::isArray( json["physics"]["rotational"]["acceleration"] ) )
for ( uint j = 0; j < 4; ++j )
physics.rotational.acceleration[j] = json["physics"]["rotational"]["acceleration"][j].asFloat();
physics.rotational.acceleration[j] = json["physics"]["rotational"]["acceleration"][j].as<float>();
}
}
@ -186,12 +193,23 @@ bool uf::Object::load( const uf::Serializer& _json ) {
uf::Asset& assetLoader = scene.getComponent<uf::Asset>();
// initialize base entity, needed for asset hooks
#define UF_OBJECT_LOAD_ASSET_HEADER(type)\
bool addBehavior = false;\
uf::Serializer target;\
if ( ext::json::isObject( metadata["system"]["assets"] ) ) {\
target = metadata["system"]["assets"];\
} else if ( ext::json::isArray( json["assets"] ) ) {\
target = json["assets"];\
} else if ( ext::json::isObject( json["assets"] ) && !ext::json::isNull( json["assets"][#type] ) ) {\
target = json["assets"][#type];\
}
#define UF_OBJECT_LOAD_ASSET(...)\
std::string canonical = "";\
std::string f = target[i].isObject() ? target[i]["filename"].asString() : target[i].asString();\
float delay = target[i].isObject() ? target[i]["delay"].asFloat() : 0;\
std::string filename = grabURI( f, json["root"].asString() );\
bool singleThreaded = target[i].isObject() ? target[i]["single threaded"].asBool() : false;\
std::string f = ext::json::isObject( target[i] ) ? target[i]["filename"].as<std::string>() : target[i].as<std::string>();\
float delay = ext::json::isObject( target[i] ) ? target[i]["delay"].as<float>() : 0;\
std::string filename = grabURI( f, json["root"].as<std::string>() );\
bool singleThreaded = ext::json::isObject( target[i] ) ? target[i]["single threaded"].as<bool>() : false;\
std::vector<std::string> allowedExtensions = {__VA_ARGS__};\
if ( std::find( allowedExtensions.begin(), allowedExtensions.end(), uf::io::extension(filename) ) == allowedExtensions.end() ) continue;\
uf::Serializer payload;\
@ -203,15 +221,7 @@ bool uf::Object::load( const uf::Serializer& _json ) {
// Audio
{
// find first valid texture in asset list
bool addBehavior = false;
uf::Serializer target;
if ( metadata["system"]["assets"].isArray() ) {
target = metadata["system"]["assets"];
} else if ( json["assets"].isArray() ) {
target = json["assets"];
} else if ( json["assets"].isObject() && !json["assets"]["audio"].isNull() ) {
target = json["assets"]["audio"];
}
UF_OBJECT_LOAD_ASSET_HEADER(audio)
for ( uint i = 0; i < target.size(); ++i ) {
UF_OBJECT_LOAD_ASSET("ogg")
}
@ -220,15 +230,7 @@ bool uf::Object::load( const uf::Serializer& _json ) {
// Texture
{
// find first valid texture in asset list
bool addBehavior = false;
uf::Serializer target;
if ( metadata["system"]["assets"].isArray() ) {
target = metadata["system"]["assets"];
} else if ( json["assets"].isArray() ) {
target = json["assets"];
} else if ( json["assets"].isObject() && !json["assets"]["textures"].isNull() ) {
target = json["assets"]["textures"];
}
UF_OBJECT_LOAD_ASSET_HEADER(textures)
for ( uint i = 0; i < target.size(); ++i ) {
UF_OBJECT_LOAD_ASSET("png")
}
@ -237,15 +239,7 @@ bool uf::Object::load( const uf::Serializer& _json ) {
// gltf
{
// find first valid texture in asset list
bool addBehavior = false;
uf::Serializer target;
if ( metadata["system"]["assets"].isArray() ) {
target = metadata["system"]["assets"];
} else if ( json["assets"].isArray() ) {
target = json["assets"];
} else if ( json["assets"].isObject() && !json["assets"]["models"].isNull() ) {
target = json["assets"]["models"];
}
UF_OBJECT_LOAD_ASSET_HEADER(models)
for ( uint i = 0; i < target.size(); ++i ) {
UF_OBJECT_LOAD_ASSET("gltf", "glb")
@ -257,15 +251,7 @@ bool uf::Object::load( const uf::Serializer& _json ) {
// lua
{
// find first valid texture in asset list
uf::Serializer target;
bool addBehavior = false;
if ( metadata["system"]["assets"].isArray() ) {
target = metadata["system"]["assets"];
} else if ( json["assets"].isArray() ) {
target = json["assets"];
} else if ( json["assets"].isObject() && !json["assets"]["scripts"].isNull() ) {
target = json["assets"]["scripts"];
}
UF_OBJECT_LOAD_ASSET_HEADER(scripts)
for ( uint i = 0; i < target.size(); ++i ) {
UF_OBJECT_LOAD_ASSET("lua")
}
@ -277,8 +263,8 @@ bool uf::Object::load( const uf::Serializer& _json ) {
if ( json["metadata"] != Json::nullValue ) {
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
if ( json["metadata"].type() == Json::stringValue ) {
std::string f = json["metadata"].asString();
std::string filename = grabURI( json["metadata"].asString(), json["root"].asString() );
std::string f = json["metadata"].as<std::string>();
std::string filename = grabURI( json["metadata"].as<std::string>(), json["root"].as<std::string>() );
if ( !metadata.readFromFile(filename) ) {
uf::iostream << "Error @ " << __FILE__ << ":" << __LINE__ << ": failed to open `" + filename + "`" << "\n";
return false;
@ -292,26 +278,19 @@ bool uf::Object::load( const uf::Serializer& _json ) {
metadata["system"]["hooks"] = hooks;
/*
for ( auto it = json["system"].begin(); it != json["system"].end(); ++it ) {
if ( metadata["system"][it.key().asString()].isNull() )
metadata["system"][it.key().asString()] = json["system"][it.key().asString()];
if ( ext::json::isNull( metadata["system"][it.key().as<std::string>()] ) )
metadata["system"][it.key().as<std::string>()] = json["system"][it.key().as<std::string>()];
}
*/
// check for children
{
uf::Serializer target;
if ( metadata["system"]["assets"].isArray() ) {
target = metadata["system"]["assets"];
} else if ( metadata["system"]["assets"].isArray() ) {
target = metadata["system"]["assets"];
} else if ( metadata["system"]["assets"].isObject() && !metadata["system"]["assets"]["entities"].isNull() ) {
target = metadata["system"]["assets"]["entities"];
}
UF_OBJECT_LOAD_ASSET_HEADER(entities)
for ( uint i = 0; i < target.size(); ++i ) {
std::string canonical = "";
std::string f = target[i].isObject() ? target[i]["filename"].asString() : target[i].asString();
float delay = target[i].isObject() ? target[i]["delay"].asFloat() : -1;
std::string filename = grabURI( f, json["root"].asString() );
std::string f = ext::json::isObject( target[i] ) ? target[i]["filename"].as<std::string>() : target[i].as<std::string>();
float delay = ext::json::isObject( target[i] ) ? target[i]["delay"].as<float>() : -1;
std::string filename = grabURI( f, json["root"].as<std::string>() );
if ( uf::io::extension(filename) != "json" ) continue;
if ( (canonical = assetLoader.load( filename )) == "" ) continue;
if ( delay > -1 ) {
@ -335,14 +314,14 @@ bool uf::Object::load( const uf::Serializer& _json ) {
}
}
// Add lights
if ( metadata["system"]["lights"].isArray() ) {
if ( ext::json::isArray( metadata["system"]["lights"] ) ) {
uf::Serializer target = metadata["system"]["lights"];
auto& pTransform = this->getComponent<pod::Transform<>>();
for ( uint i = 0; i < target.size(); ++i ) {
uf::Serializer json = target[i];
std::vector<pod::Vector4f> orientations;
if ( json["ignore"].asBool() ) continue;
if ( json["transform"]["orientation"].isNull() && json["shadows"]["fov"].asFloat() == 0.0f ) {
if ( json["ignore"].as<bool>() ) continue;
if ( ext::json::isNull( json["transform"]["orientation"] ) && json["shadows"]["fov"].as<float>() == 0.0f ) {
orientations.reserve(6);
orientations.push_back({0, 0, 0, -1});
orientations.push_back({0, 0.707107, 0, -0.707107});
@ -353,49 +332,50 @@ bool uf::Object::load( const uf::Serializer& _json ) {
json["shadows"]["fov"] = 90.0f;
} else {
pod::Vector4f orientation;
if ( json["transform"]["orientation"].isArray() ) {
if ( ext::json::isArray( json["transform"]["orientation"] ) ) {
orientation = pTransform.orientation;
} else {
for ( uint j = 0; j < 4; ++j ) orientation[j] = json["transform"]["orientation"][j].asFloat();
for ( uint j = 0; j < 4; ++j ) orientation[j] = json["transform"]["orientation"][j].as<float>();
}
orientations.push_back(orientation);
}
uf::Object* target = this;
for ( auto& orientation : orientations ) {
std::string fname = "/light.json";
if ( json["system"]["filename"].isString() ) fname = json["system"]["filename"].asString();
if ( json["system"]["filename"].is<std::string>() ) fname = json["system"]["filename"].as<std::string>();
auto* light = target->loadChildPointer(fname, false);
if ( target == this ) target = light;
auto& metadata = light->getComponent<uf::Serializer>();
auto& transform = light->getComponent<pod::Transform<>>();
if ( json["transform"]["position"].isArray() ) {
if ( ext::json::isArray( json["transform"]["position"] ) ) {
for ( uint j = 0; j < 3; ++j )
transform.position[j] = json["transform"]["position"][j].asFloat();
transform.position[j] = json["transform"]["position"][j].as<float>();
} else {
transform.position = pTransform.position;
}
for ( uint j = 0; j < 4; ++j )
transform.orientation[j] = orientation[j];
if ( !json["color"].isNull() ) metadata["light"]["color"] = json["color"];
if ( !json["radius"].isNull() ) metadata["light"]["radius"] = json["radius"];
if ( !json["power"].isNull() ) metadata["light"]["power"] = json["power"];
if ( !json["shadows"].isNull() ) metadata["light"]["shadows"] = json["shadows"];
if ( !json["flicker"].isNull() ) metadata["light"]["flicker"] = json["flicker"];
if ( !json["fade"].isNull() ) metadata["light"]["fade"] = json["fade"];
if ( !ext::json::isNull( json["color"] ) ) metadata["light"]["color"] = json["color"];
if ( !ext::json::isNull( json["radius"] ) ) metadata["light"]["radius"] = json["radius"];
if ( !ext::json::isNull( json["power"] ) ) metadata["light"]["power"] = json["power"];
if ( !ext::json::isNull( json["shadows"] ) ) metadata["light"]["shadows"] = json["shadows"];
if ( !ext::json::isNull( json["flicker"] ) ) metadata["light"]["flicker"] = json["flicker"];
if ( !ext::json::isNull( json["fade"] ) ) metadata["light"]["fade"] = json["fade"];
if ( !json["system"]["track"].isNull() ) metadata["system"]["track"] = json["system"]["track"];
if ( !ext::json::isNull( json["system"]["track"] ) ) metadata["system"]["track"] = json["system"]["track"];
light->initialize();
}
}
}
return true;
}
uf::Object& uf::Object::loadChild( const std::string& f, bool initialize ) {
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
uf::Serializer json;
std::string filename = grabURI( f, metadata["system"]["root"].asString() );
std::string filename = grabURI( f, metadata["system"]["root"].as<std::string>() );
if ( !json.readFromFile(filename) ) {
uf::iostream << "Error @ " << __FILE__ << ":" << __LINE__ << ": failed to open `" + filename + "`" << "\n";
return ::null;
@ -406,8 +386,8 @@ uf::Object& uf::Object::loadChild( const std::string& f, bool initialize ) {
return this->loadChild(json, initialize);
}
uf::Object& uf::Object::loadChild( const uf::Serializer& json, bool initialize ) {
std::string type = json["type"].asString();
if ( json["ignore"].asBool() ) return ::null;
std::string type = json["type"].as<std::string>();
if ( json["ignore"].as<bool>() ) return ::null;
uf::Entity& entity = uf::instantiator::instantiate(type);
uf::Object& object = entity.as<uf::Object>();

View File

@ -3,10 +3,10 @@
#include <uf/utils/camera/camera.h>
#include <uf/utils/renderer/renderer.h>
UF_BEHAVIOR_ENTITY_CPP_BEGIN(Scene)
UF_BEHAVIOR_ENTITY_CPP_BEGIN(uf::Scene)
#define this ((uf::Scene*) &self)
void uf::SceneBehavior::initialize( uf::Object& self ) {
uf::renderer::scenes.push_back(this);
// uf::renderer::scenes.push_back(this);
uf::renderer::states::rebuild = true;
this->addHook( "system:Renderer.QueueRebuild", [&](const std::string& event)->std::string{
@ -15,7 +15,7 @@ void uf::SceneBehavior::initialize( uf::Object& self ) {
});
this->addHook( "system:Destroy", [&](const std::string& event)->std::string{
uf::Serializer json = event;
size_t uid = json["uid"].asUInt64();
size_t uid = json["uid"].as<size_t>();
if ( uid <= 0 ) return "false";
auto* target = this->findByUid(uid);
if ( !target ) return "false";
@ -32,8 +32,10 @@ void uf::SceneBehavior::tick( uf::Object& self ) {
void uf::SceneBehavior::render( uf::Object& self ) {
}
void uf::SceneBehavior::destroy( uf::Object& self ) {
/*
auto it = std::find(uf::renderer::scenes.begin(), uf::renderer::scenes.end(), this);
if ( it != uf::renderer::scenes.end() ) uf::renderer::scenes.erase(it);
*/
uf::renderer::states::rebuild = true;
}
#undef self

View File

@ -2,12 +2,14 @@
#include <uf/utils/string/ext.h>
#include <uf/utils/camera/camera.h>
#include <uf/utils/renderer/renderer.h>
#include <regex>
UF_OBJECT_REGISTER_BEGIN(Scene)
UF_OBJECT_REGISTER_BEHAVIOR(EntityBehavior)
UF_OBJECT_REGISTER_BEHAVIOR(ObjectBehavior)
UF_OBJECT_REGISTER_BEHAVIOR(SceneBehavior)
UF_OBJECT_REGISTER_BEGIN(uf::Scene)
UF_OBJECT_REGISTER_BEHAVIOR(uf::EntityBehavior)
UF_OBJECT_REGISTER_BEHAVIOR(uf::ObjectBehavior)
UF_OBJECT_REGISTER_BEHAVIOR(uf::SceneBehavior)
UF_OBJECT_REGISTER_END()
uf::Scene::Scene() UF_BEHAVIOR_ENTITY_CPP_ATTACH(uf::Scene)
uf::Entity& uf::Scene::getController() {
static uf::Entity* cachedController = NULL;
if ( uf::renderer::currentRenderMode ) {
@ -35,16 +37,12 @@ const uf::Entity& uf::Scene::getController() const {
uf::Scene& scene = *const_cast<uf::Scene*>(this);
return scene.getController();
}
#include <regex>
std::vector<uf::Scene*> uf::scene::scenes;
uf::Scene& uf::scene::loadScene( const std::string& name, const std::string& filename ) {
uf::Scene* scene;
if ( uf::instantiator::objects->has( name ) ) {
scene = (uf::Scene*) &uf::instantiator::instantiate( name );
} else {
scene = new uf::Scene;
}
uf::scene::scenes.push_back(scene);
uf::Scene* scene = uf::instantiator::objects->has( name ) ? (uf::Scene*) &uf::instantiator::instantiate( name ) : new uf::Scene;
// uf::scene::scenes.insert(uf::scene::scenes.begin(), scene);
uf::scene::scenes.emplace_back( scene );
std::string target = name;
@ -60,13 +58,11 @@ uf::Scene& uf::scene::loadScene( const std::string& name, const std::string& fil
return *scene;
}
uf::Scene& uf::scene::loadScene( const std::string& name, const uf::Serializer& data ) {
uf::Scene* scene;
if ( uf::instantiator::objects->has( name ) ) {
scene = (uf::Scene*) &uf::instantiator::instantiate( name );
} else {
scene = new uf::Scene;
}
uf::scene::scenes.push_back(scene);
uf::Scene* scene = uf::instantiator::objects->has( name ) ? (uf::Scene*) &uf::instantiator::instantiate( name ) : new uf::Scene;
// uf::scene::scenes.insert(uf::scene::scenes.begin(), scene);
uf::scene::scenes.emplace_back( scene );
if ( data != "" ) scene->load(data);
scene->initialize();
return *scene;

View File

@ -192,28 +192,28 @@ void UF_API ext::discord::initialize(){
uf::hooks.addHook( "discord:Activity.Update", [&](const std::string& event)->std::string{
static uf::Serializer canonical; if ( canonical["details"].isNull() ) {
static uf::Serializer canonical; if ( ext::json::isNull( canonical["details"] ) ) {
canonical["large image"] = "icon";
canonical["large text"] = "Playing";
}
uf::Serializer json = event;
{
if ( json["details"].isString() ) canonical["details"] = json["details"];
if ( json["state"].isString() ) canonical["state"] = json["state"];
if ( json["small image"].isString() ) canonical["small image"] = json["small image"];
if ( json["small text"].isString() ) canonical["small text"] = json["small text"];
if ( json["large image"].isString() ) canonical["large image"] = json["large image"];
if ( json["large text"].isString() ) canonical["large text"] = json["large text"];
if ( json["details"].is<std::string>() ) canonical["details"] = json["details"];
if ( json["state"].is<std::string>() ) canonical["state"] = json["state"];
if ( json["small image"].is<std::string>() ) canonical["small image"] = json["small image"];
if ( json["small text"].is<std::string>() ) canonical["small text"] = json["small text"];
if ( json["large image"].is<std::string>() ) canonical["large image"] = json["large image"];
if ( json["large text"].is<std::string>() ) canonical["large text"] = json["large text"];
}
::discord::Activity activity{};
if ( canonical["details"].isString() ) activity.SetDetails(canonical["details"].asCString());
if ( canonical["state"].isString() ) activity.SetState(canonical["state"].asCString());
if ( canonical["small image"].isString() ) activity.GetAssets().SetSmallImage(canonical["small image"].asCString());
if ( canonical["small text"].isString() ) activity.GetAssets().SetSmallText(canonical["small text"].asCString());
if ( canonical["large image"].isString() ) activity.GetAssets().SetLargeImage(canonical["large image"].asCString());
if ( canonical["large text"].isString() ) activity.GetAssets().SetLargeText(canonical["large text"].asCString());
if ( canonical["details"].is<std::string>() ) activity.SetDetails(canonical["details"].asCString());
if ( canonical["state"].is<std::string>() ) activity.SetState(canonical["state"].asCString());
if ( canonical["small image"].is<std::string>() ) activity.GetAssets().SetSmallImage(canonical["small image"].asCString());
if ( canonical["small text"].is<std::string>() ) activity.GetAssets().SetSmallText(canonical["small text"].asCString());
if ( canonical["large image"].is<std::string>() ) activity.GetAssets().SetLargeImage(canonical["large image"].asCString());
if ( canonical["large text"].is<std::string>() ) activity.GetAssets().SetLargeText(canonical["large text"].asCString());
activity.SetType(::discord::ActivityType::Playing);
state.core->ActivityManager().UpdateActivity(activity, [](::discord::Result result) {
std::cout << ((result == ::discord::Result::Ok) ? "Succeeded" : "Failed") << " updating activity!\n";

File diff suppressed because it is too large Load Diff

View File

@ -2,161 +2,97 @@
sol::state ext::lua::state;
std::string ext::lua::main = "./data/scripts/main.lua";
std::unordered_map<std::string, std::string> ext::lua::modules;
#include <uf/utils/math/transform.h>
#include <uf/utils/math/physics.h>
#include <uf/utils/serialize/serializer.h>
#include <uf/engine/asset/asset.h>
#include <uf/engine/object/object.h>
#include <uf/engine/object/behaviors/lua.h>
#include <uf/utils/string/io.h>
#include <uf/utils/string/ext.h>
#include <uf/utils/window/window.h>
#include <uf/utils/audio/audio.h>
sol::table ext::lua::createTable() {
return sol::table(ext::lua::state, sol::create);
}
std::string ext::lua::sanitize( const std::string& dirty, int index ) {
auto split = uf::string::split( dirty, "::" );
if ( index < 0 ) index = split.size() + index;
std::string part = split.at(index);
part = uf::string::replace( part, "<>", "" );
return part;
}
std::optional<std::string> ext::lua::encode( sol::table table ) {
sol::protected_function fun = ext::lua::state["json"]["encode"];
auto result = fun( table );
if ( !result.valid() ) {
sol::error err = result;
uf::iostream << err.what() << "\n";
return "{}";
}
return result;
}
std::optional<sol::table> ext::lua::decode( const std::string& string ) {
sol::protected_function fun = ext::lua::state["json"]["decode"];
auto result = fun( string );
if ( !result.valid() ) {
sol::error err = result;
uf::iostream << err.what() << "\n";
return createTable();
}
return result;
}
std::vector<std::function<void()>>* ext::lua::onInitializationFunctions = NULL;
void ext::lua::onInitialization( const std::function<void()>& function ) {
if ( !ext::lua::onInitializationFunctions ) {
ext::lua::onInitializationFunctions = new std::vector<std::function<void()>>;
}
auto& functions = *ext::lua::onInitializationFunctions;
functions.emplace_back(function);
}
void ext::lua::initialize() {
state.open_libraries(sol::lib::base, sol::lib::package, sol::lib::table, sol::lib::math, sol::lib::string);
state.open_libraries(sol::lib::base, sol::lib::package, sol::lib::table, sol::lib::math, sol::lib::string, sol::lib::ffi, sol::lib::jit);
POD_LUA_REGISTER_USERTYPE_BEGIN(Matrix4f)
"value", []( pod::Matrix4f& self, const size_t& index ) {
return self[index];
// load modules
for ( auto pair : modules ) {
const std::string& name = pair.first;
const std::string& script = pair.second;
if ( uf::io::extension(script) == "lua" ) {
state.require_file(name, uf::io::resolveURI( script ), true);
} else {
state.require_script(name, script, true);
}
POD_LUA_REGISTER_USERTYPE_END()
POD_LUA_REGISTER_USERTYPE_BEGIN(Vector3f)
POD_LUA_REGISTER_USERTYPE_MEMBER(Vector3f, x),
POD_LUA_REGISTER_USERTYPE_MEMBER(Vector3f, y),
POD_LUA_REGISTER_USERTYPE_MEMBER(Vector3f, z)
POD_LUA_REGISTER_USERTYPE_END()
POD_LUA_REGISTER_USERTYPE_BEGIN(Vector4f)
POD_LUA_REGISTER_USERTYPE_MEMBER(Vector4f, x),
POD_LUA_REGISTER_USERTYPE_MEMBER(Vector4f, y),
POD_LUA_REGISTER_USERTYPE_MEMBER(Vector4f, z),
POD_LUA_REGISTER_USERTYPE_MEMBER(Vector4f, w)
POD_LUA_REGISTER_USERTYPE_END()
POD_LUA_REGISTER_USERTYPE_BEGIN(Quaternion<>)
POD_LUA_REGISTER_USERTYPE_MEMBER(Quaternion<>, x),
POD_LUA_REGISTER_USERTYPE_MEMBER(Quaternion<>, y),
POD_LUA_REGISTER_USERTYPE_MEMBER(Quaternion<>, z),
POD_LUA_REGISTER_USERTYPE_MEMBER(Quaternion<>, w)
POD_LUA_REGISTER_USERTYPE_END()
POD_LUA_REGISTER_USERTYPE_BEGIN(Transform<>)
POD_LUA_REGISTER_USERTYPE_MEMBER(Transform<>, position),
POD_LUA_REGISTER_USERTYPE_MEMBER(Transform<>, scale),
POD_LUA_REGISTER_USERTYPE_MEMBER(Transform<>, up),
POD_LUA_REGISTER_USERTYPE_MEMBER(Transform<>, right),
POD_LUA_REGISTER_USERTYPE_MEMBER(Transform<>, forward),
POD_LUA_REGISTER_USERTYPE_MEMBER(Transform<>, orientation),
POD_LUA_REGISTER_USERTYPE_MEMBER(Transform<>, model),
"move", []( pod::Transform<>& self, sol::variadic_args va ) {
auto it = va.begin();
if ( va.size() == 1 ) {
pod::Vector3f delta = *it++;
self = uf::transform::move( self, delta );
} else if ( va.size() == 2 ) {
pod::Vector3f axis = *it++;
double delta = *it++;
self = uf::transform::move( self, axis, delta );
}
},
"rotate", []( pod::Transform<>& self, sol::variadic_args va ) {
auto it = va.begin();
if ( va.size() == 1 ) {
pod::Quaternion<> delta = *it++;
self = uf::transform::rotate( self, delta );
} else if ( va.size() == 2 ) {
pod::Vector3f axis = *it++;
double delta = *it++;
self = uf::transform::rotate( self, axis, delta );
}
}
POD_LUA_REGISTER_USERTYPE_END()
UF_LUA_REGISTER_USERTYPE_BEGIN(Object)
"uid", &uf::Object::getUid,
"name", &uf::Object::getName,
"getComponent", [](uf::Object& self, const std::string& type, sol::this_state L ) {
sol::variadic_results values;
if ( type == "Metadata" ) {
std::string serialized = self.getComponent<uf::Serializer>();
sol::table table = state["json"]["decode"]( serialized );
values.push_back( { L, sol::in_place, table } );
} else if ( type == "Transform" ) {
values.push_back( { L, sol::in_place, &self.getComponent<pod::Transform<>>() } );
}
return values;
},
"setComponent", [](uf::Object& self, const std::string& type, sol::variadic_args va ) {
auto value = *va.begin();
if ( type == "Metadata" ) {
std::string encoded = state["json"]["encode"]( value.as<sol::table>() );
self.getComponent<uf::Serializer>().merge(encoded);
} else if ( type == "Transform" ) {
self.getComponent<pod::Transform<>>() = value.as<pod::Transform<>>();
}
},
"bind", [](uf::Object& self, const std::string& type, const sol::function& fun ) {
if ( !self.hasBehavior<uf::LuaBehavior>() ) uf::instantiator::bind( "LuaBehavior", self );
pod::Behavior* behaviorPointer = NULL;
auto& behaviors = self.getBehaviors();
for ( auto& b : behaviors ) {
if ( b.type != self.getType<uf::LuaBehavior>() ) continue;
behaviorPointer = &b;
break;
}
if ( !behaviorPointer ) return false;
pod::Behavior& behavior = *behaviorPointer;
pod::Behavior::function_t* functionPointer = NULL;
if ( type == "initialize" ) functionPointer = &behavior.initialize;
else if ( type == "tick" ) functionPointer = &behavior.tick;
else if ( type == "render" ) functionPointer = &behavior.render;
else if ( type == "destroy" ) functionPointer = &behavior.destroy;
if ( !functionPointer ) return false;
pod::Behavior::function_t& function = *functionPointer;
function = [fun]( uf::Object& s ) {
fun(s);
};
return true;
},
"findByUid", []( uf::Object& self, const size_t& index )->uf::Object&{
auto* pointer = self.findByUid( index );
if ( pointer ) return pointer->as<uf::Object>();
static uf::Object null;
return null;
},
"findByName", []( uf::Object& self, const std::string& index )->uf::Object&{
auto* pointer = self.findByName( index );
if ( pointer ) return pointer->as<uf::Object>();
static uf::Object null;
return null;
},
"loadChild", []( uf::Object& self, const std::string& filename )->uf::Object&{
auto* pointer = self.loadChildPointer( filename );
if ( pointer ) return pointer->as<uf::Object>();
static uf::Object null;
return null;
},
"getChildren", []( uf::Object& self )->sol::table{
sol::table table(ext::lua::state, sol::create);
for ( auto* child : self.getChildren() ) {
table.add(&child->as<uf::Object>());
}
return table;
},
"getParent", []( uf::Object& self )->uf::Object&{
return self.getParent().as<uf::Object>();
}
UF_LUA_REGISTER_USERTYPE_END()
}
// load on-initialization defines
if ( ext::lua::onInitializationFunctions ) {
auto& functions = *ext::lua::onInitializationFunctions;
for ( auto& function : functions ) function();
}
// `hooks` table
{
auto hooks = state["hooks"].get_or_create<sol::table>();
hooks["add"] = []( const std::string& name, const sol::function& function ) {
uf::hooks.addHook( name, [function]( const std::string& payload )->std::string{
return function( payload );
sol::table table = ext::lua::state["json"]["decode"]( payload );
auto result = function( table );
if ( !result.valid() ) {
sol::error err = result;
uf::iostream << err.what() << "\n";
return "false";
}
return "true";
});
};
hooks["call"] = []( const std::string& name, const std::string& payload ) {
hooks["call"] = []( const std::string& name, sol::table table = createTable() ) {
uf::Serializer payload = table;
return uf::hooks.call( name, payload );
};
}
@ -169,6 +105,54 @@ void ext::lua::initialize() {
static uf::Object null;
return null;
};
entities["currentScene"] = []()->uf::Object&{
return uf::scene::getCurrentScene().as<uf::Object>();
};
entities["controller"] = []()->uf::Object&{
return uf::scene::getCurrentScene().getController().as<uf::Object>();
};
entities["destroy"] = []( uf::Object& object ){
object.getParent().removeChild(object);
object.destroy();
// delete &object;
};
}
// `string` table
{
auto string = state["string"].get_or_create<sol::table>();
string["extension"] = []( const std::string& filename ) {
return uf::io::extension( filename );
};
string["resolveURI"] = []( const std::string& filename ) {
return uf::io::resolveURI( filename );
};
string["si"] = []( sol::variadic_args va ) {
auto it = va.begin();
double value = *(it++);
std::string unit = *(it++);
size_t precision = va.size() > 2 ? *(it++) : 3;
return uf::string::si( value, unit, precision );
};
}
// `io` table
{
auto io = state["io"].get_or_create<sol::table>();
io["print"] = []( sol::variadic_args va ) {
size_t count = va.size();
for ( auto value : va ) {
std::string str = ext::lua::state["tostring"]( value );
uf::iostream << str;
if ( --count != 0 ) uf::iostream << "\t";
}
uf::iostream << "\n";
};
}
// `math` table
{
auto math = state["math"].get_or_create<sol::table>();
math["clamp"] = []( double value, double min, double max ) {
return std::clamp( value, min, max );
};
}
// `time` table
{
@ -179,11 +163,27 @@ void ext::lua::initialize() {
}
// `json` table
{
auto json = state.require_file("json", "./data/scripts/json.lua", true);
state["json"]["pretty"] = []( const std::string& json )->std::string{
uf::Serializer serializer = json;
return serializer.serialize();
};
state["json"]["readFromFile"] = []( const std::string& filename ){
uf::Serializer serializer;
serializer.readFromFile( filename );
std::string string = serializer.serialize(false);
auto decoded = decode( string );
return decoded ? decoded.value() : ext::lua::createTable();
};
state["json"]["writeToFile"] = []( sol::table table, const std::string& path ) {
if ( uf::io::extension(path) != "json" ) return false;
auto encoded = encode( table );
if ( encoded ) {
uf::Serializer json = encoded.value();
json.writeToFile( path );
return true;
}
return false;
};
}
// `window` table
{
@ -198,14 +198,14 @@ bool ext::lua::run( const std::string& s, bool safe ) {
// is file
if ( uf::io::extension(s) == "lua" ) {
if ( safe ) {
auto result = state.safe_script_file( s, sol::script_pass_on_error );
auto result = state.safe_script_file( uf::io::resolveURI( s ), sol::script_pass_on_error );
if ( !result.valid() ) {
sol::error err = result;
uf::iostream << "Invalid call to Lua script: " << err.what() << "\n";
uf::iostream << err.what() << "\n";
return false;
}
} else {
state.script_file( s );
state.script_file( uf::io::resolveURI( s ) );
}
// is string with lua
} else {
@ -213,7 +213,7 @@ bool ext::lua::run( const std::string& s, bool safe ) {
auto result = state.safe_script( s, sol::script_pass_on_error );
if ( !result.valid() ) {
sol::error err = result;
uf::iostream << "Invalid call to Lua script: " << err.what() << "\n";
uf::iostream << err.what() << "\n";
return false;
}
} else {
@ -225,20 +225,41 @@ bool ext::lua::run( const std::string& s, bool safe ) {
pod::LuaScript ext::lua::script( const std::string& filename ) {
pod::LuaScript script;
script.filename = filename;
script.file = filename;
script.env = sol::environment( ext::lua::state, sol::create, ext::lua::state.globals() );
return script;
}
bool ext::lua::run( const pod::LuaScript& s ) {
std::string script = s.header + "\n" + uf::io::readAsString( s.filename );
auto result = state.safe_script( script, s.env, sol::script_pass_on_error );
if ( !result.valid() ) {
sol::error err = result;
uf::iostream << "Invalid call to Lua script: " << err.what() << "\n";
return false;
bool ext::lua::run( const pod::LuaScript& s, bool safe ) {
// is file
if ( uf::io::extension(s.file) == "lua" ) {
if ( safe ) {
auto result = state.safe_script_file( s.file, s.env, sol::script_pass_on_error );
if ( !result.valid() ) {
sol::error err = result;
uf::iostream << err.what() << "\n";
return false;
}
} else {
state.script_file( s.file );
}
// is string with lua
} else {
if ( safe ) {
auto result = state.safe_script( s.file, s.env, sol::script_pass_on_error );
if ( !result.valid() ) {
sol::error err = result;
uf::iostream << err.what() << "\n";
return false;
}
} else {
state.script( s.file );
}
}
return true;
}
void ext::lua::terminate() {
if ( ext::lua::onInitializationFunctions ) {
delete ext::lua::onInitializationFunctions;
ext::lua::onInitializationFunctions = NULL;
}
}

View File

@ -0,0 +1,19 @@
#include <uf/ext/lua/lua.h>
#include <uf/engine/asset/asset.h>
UF_LUA_REGISTER_USERTYPE(uf::Asset,
UF_LUA_REGISTER_USERTYPE_DEFINE( load, []( uf::Asset& asset, const std::string& uri, const std::string& callback = "" ) {
if ( callback == "" )
asset.load( uri );
else
asset.load( uri, callback );
}),
UF_LUA_REGISTER_USERTYPE_DEFINE( cache, []( uf::Asset& asset, const std::string& uri, const std::string& callback = "" ) {
if ( callback == "" )
asset.cache( uri );
else
asset.cache( uri, callback );
}),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Asset::getOriginal )
)

View File

@ -0,0 +1,33 @@
#include <uf/ext/lua/lua.h>
#include <uf/utils/audio/audio.h>
UF_LUA_REGISTER_USERTYPE(uf::Audio,
sol::call_constructor, sol::initializers( []( uf::Audio& self ){},
[]( uf::Audio& self, const std::string& filename = "", double volume = 1 ){
if ( filename != "" ) self.load(filename);
self.setVolume(volume);
}),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Audio::initialized ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Audio::playing ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Audio::destroy ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Audio::load ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Audio::play ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Audio::stop ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Audio::getTime ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Audio::setTime ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Audio::getDuration ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Audio::setPosition ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Audio::setOrientation ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Audio::setVolume ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Audio::getPitch ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Audio::setPitch ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Audio::getGain ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Audio::setGain ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Audio::getRolloffFactor ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Audio::setRolloffFactor ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Audio::getMaxDistance ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Audio::setMaxDistance ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Audio::getVolume ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Audio::getFilename )
)

View File

@ -0,0 +1,7 @@
#include <uf/ext/lua/lua.h>
#include <uf/utils/camera/camera.h>
UF_LUA_REGISTER_USERTYPE(uf::Camera,
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Camera::update )
)

View File

@ -0,0 +1,9 @@
#include <uf/ext/lua/lua.h>
#include <uf/utils/math/matrix.h>
UF_LUA_REGISTER_USERTYPE(pod::Matrix4f,
UF_LUA_REGISTER_USERTYPE_DEFINE( m, []( pod::Matrix4f& self, const size_t& index ) {
return self[index];
})
)

View File

@ -0,0 +1,163 @@
#include <uf/ext/lua/lua.h>
#include <uf/utils/math/transform.h>
#include <uf/utils/audio/audio.h>
#include <uf/utils/camera/camera.h>
#include <uf/engine/object/object.h>
#include <uf/engine/asset/asset.h>
#include <uf/engine/object/behaviors/lua.h>
UF_LUA_REGISTER_USERTYPE(uf::Object,
sol::call_constructor, sol::initializers( []( uf::Object& self, sol::object arg, bool init = true ){
if ( arg.is<std::string>() ) {
self.load( arg.as<std::string>() );
} else if ( arg.is<sol::table>() ) {
auto encoded = ext::lua::encode( arg.as<sol::table>() );
if ( encoded ) {
uf::Serializer json = encoded.value();
self.load(json);
}
}
if ( init ) {
self.initialize();
}
}),
UF_LUA_REGISTER_USERTYPE_DEFINE( uid, &uf::Object::getUid ),
UF_LUA_REGISTER_USERTYPE_DEFINE( name, &uf::Object::getName ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Object::formatHookName ),
UF_LUA_REGISTER_USERTYPE_DEFINE( getComponent, [](uf::Object& self, const std::string& type )->sol::object{
#define UF_LUA_RETRIEVE_COMPONENT( T )\
if ( type == UF_NS_GET_LAST(T) ) return sol::make_object( ext::lua::state, &self.getComponent<T>() );
if ( type == "Metadata" ) {
auto& metadata = self.getComponent<uf::Serializer>();
auto decoded = ext::lua::decode( metadata );
if ( decoded ) {
sol::table table = decoded.value();
return sol::make_object( ext::lua::state, table );
}
}
UF_LUA_RETRIEVE_COMPONENT(pod::Transform<>)
UF_LUA_RETRIEVE_COMPONENT(uf::Audio)
UF_LUA_RETRIEVE_COMPONENT(uf::Asset)
UF_LUA_RETRIEVE_COMPONENT(uf::Camera)
return sol::make_object( ext::lua::state, sol::lua_nil );
}),
UF_LUA_REGISTER_USERTYPE_DEFINE( setComponent, [](uf::Object& self, const std::string& type, sol::object value ) {
#define UF_LUA_UPDATE_COMPONENT( T )\
else if ( type == UF_NS_GET_LAST(T) ) self.getComponent<T>() = std::move(value.as<T>());
if ( type == "Metadata" ) {
auto encoded = ext::lua::encode( value.as<sol::table>() );
if ( encoded ) {
auto& metadata = self.getComponent<uf::Serializer>();
std::string str = encoded.value();
uf::Serializer hooks = metadata["system"]["hooks"];
metadata.merge( str, false );
metadata["system"]["hooks"] = hooks;
}
}
UF_LUA_UPDATE_COMPONENT(pod::Transform<>)
UF_LUA_UPDATE_COMPONENT(uf::Audio)
UF_LUA_UPDATE_COMPONENT(uf::Asset)
UF_LUA_UPDATE_COMPONENT(uf::Camera)
/*
} else if ( type == "Transform" ) {
self.getComponent<pod::Transform<>>() = value.as<pod::Transform<>>();
}
*/
}),
UF_LUA_REGISTER_USERTYPE_DEFINE( bind, [](uf::Object& self, const std::string& type, sol::protected_function fun ) {
if ( !self.hasBehavior<uf::LuaBehavior>() ) uf::instantiator::bind( "LuaBehavior", self );
pod::Behavior* behaviorPointer = NULL;
auto& behaviors = self.getBehaviors();
for ( auto& b : behaviors ) {
if ( b.type != self.getType<uf::LuaBehavior>() ) continue;
behaviorPointer = &b;
break;
}
if ( !behaviorPointer ) return false;
pod::Behavior& behavior = *behaviorPointer;
pod::Behavior::function_t* functionPointer = NULL;
if ( type == "initialize" ) functionPointer = &behavior.initialize;
else if ( type == "tick" ) functionPointer = &behavior.tick;
else if ( type == "render" ) functionPointer = &behavior.render;
else if ( type == "destroy" ) functionPointer = &behavior.destroy;
if ( !functionPointer ) return false;
pod::Behavior::function_t& function = *functionPointer;
function = [fun]( uf::Object& s ) {
auto result = fun(s);
if ( !result.valid() ) {
sol::error err = result;
uf::iostream << err.what() << "\n";
}
};
return true;
}),
UF_LUA_REGISTER_USERTYPE_DEFINE( findByUid, []( uf::Object& self, const size_t& index )->uf::Object&{
auto* pointer = self.findByUid( index );
if ( pointer ) return pointer->as<uf::Object>();
static uf::Object null;
return null;
}),
UF_LUA_REGISTER_USERTYPE_DEFINE( findByName, []( uf::Object& self, const std::string& index )->uf::Object&{
auto* pointer = self.findByName( index );
if ( pointer ) return pointer->as<uf::Object>();
static uf::Object null;
return null;
}),
UF_LUA_REGISTER_USERTYPE_DEFINE( addChild, []( uf::Object& self, uf::Object& child )->uf::Object&{
self.addChild( child );
return self;
}),
UF_LUA_REGISTER_USERTYPE_DEFINE( removeChild, []( uf::Object& self, uf::Object& child )->uf::Object&{
self.removeChild( child );
return self;
}),
UF_LUA_REGISTER_USERTYPE_DEFINE( loadChild, []( uf::Object& self, const std::string& filename, bool init = true )->uf::Object&{
auto* pointer = self.loadChildPointer( filename, init );
if ( pointer ) return pointer->as<uf::Object>();
static uf::Object null;
return null;
}),
UF_LUA_REGISTER_USERTYPE_DEFINE( getChildren, []( uf::Object& self )->sol::table{
sol::table table = ext::lua::createTable();
for ( auto* child : self.getChildren() ) {
table.add(&child->as<uf::Object>());
}
return table;
}),
UF_LUA_REGISTER_USERTYPE_DEFINE( getParent, []( uf::Object& self )->uf::Object&{
return self.getParent().as<uf::Object>();
}),
UF_LUA_REGISTER_USERTYPE_DEFINE( addHook, []( uf::Object& self, const std::string& name, const sol::function& function ) {
self.addHook( name, [function]( const std::string& payload )->std::string{
auto decoded = ext::lua::decode( payload );
if ( decoded ) {
sol::table table = decoded.value();
auto result = function( table );
if ( !result.valid() ) {
sol::error err = result;
uf::iostream << err.what() << "\n";
return "false";
}
return "true";
}
return "false";
});
}),
UF_LUA_REGISTER_USERTYPE_DEFINE( callHook, []( uf::Object& self, const std::string& name, sol::table table = ext::lua::createTable() ) {
uf::Serializer payload = table;
self.callHook( name, payload );
}),
UF_LUA_REGISTER_USERTYPE_DEFINE( queueHook, []( uf::Object& self, const std::string& name, sol::table table, float delay = 0.0f ) {
uf::Serializer payload = table;
self.queueHook( name, payload, delay );
}),
UF_LUA_REGISTER_USERTYPE_DEFINE( __tostring, []( uf::Object& self ) {
return self.getName() + ": " + std::to_string( self.getUid() );
})
)

View File

@ -0,0 +1,35 @@
#include <uf/ext/lua/lua.h>
#include <uf/utils/math/quaternion.h>
UF_LUA_REGISTER_USERTYPE(pod::Quaternion<>,
sol::call_constructor, sol::initializers(
[]( pod::Quaternion<>& self, const pod::Quaternion<>& copy = {} ) {
self = copy;
},
[]( pod::Quaternion<>& self, float x, float y, float z, float w ) {
self = uf::vector::create(x, y, z, w);
}
),
UF_LUA_REGISTER_USERTYPE_MEMBER(pod::Quaternion<>::x),
UF_LUA_REGISTER_USERTYPE_MEMBER(pod::Quaternion<>::y),
UF_LUA_REGISTER_USERTYPE_MEMBER(pod::Quaternion<>::z),
UF_LUA_REGISTER_USERTYPE_MEMBER(pod::Quaternion<>::w),
UF_LUA_REGISTER_USERTYPE_DEFINE(v, []( pod::Quaternion<>& self, const size_t& index ) {
return self[index];
}),
UF_LUA_REGISTER_USERTYPE_DEFINE( __tostring, []( pod::Quaternion<>& self ) {
std::stringstream ss;
ss << "Quaterion(" << self.x << ", " << self.y << ", " << self.z << ", " << self.w << ")";
return ss.str();
}),
UF_LUA_REGISTER_USERTYPE_DEFINE(axisAngle, []( sol::object arg, float angle ){
if ( arg.is<pod::Vector3f>() ) {
return uf::quaternion::axisAngle( arg.as<pod::Vector3f>(), angle );
} else if ( arg.is<sol::table>() ) {
sol::table table = arg.as<sol::table>();
return uf::quaternion::axisAngle( pod::Vector3f{ table[0], table[1], table[2] }, angle );
}
return pod::Quaternion<>{};
})
)

View File

@ -0,0 +1,14 @@
#include <uf/ext/lua/lua.h>
#include <uf/utils/math/physics.h>
UF_LUA_REGISTER_USERTYPE(uf::Timer<>,
UF_LUA_REGISTER_USERTYPE_DEFINE( elapsed, []( uf::Timer<>& self ) {
return self.elapsed().asDouble();
}),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Timer<>::start ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Timer<>::stop ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Timer<>::reset ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Timer<>::update ),
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Timer<>::running )
)

View File

@ -0,0 +1,35 @@
#include <uf/ext/lua/lua.h>
#include <uf/utils/math/transform.h>
UF_LUA_REGISTER_USERTYPE(pod::Transform<>,
UF_LUA_REGISTER_USERTYPE_MEMBER(pod::Transform<>::position),
UF_LUA_REGISTER_USERTYPE_MEMBER(pod::Transform<>::scale),
UF_LUA_REGISTER_USERTYPE_MEMBER(pod::Transform<>::up),
UF_LUA_REGISTER_USERTYPE_MEMBER(pod::Transform<>::right),
UF_LUA_REGISTER_USERTYPE_MEMBER(pod::Transform<>::forward),
UF_LUA_REGISTER_USERTYPE_MEMBER(pod::Transform<>::orientation),
UF_LUA_REGISTER_USERTYPE_MEMBER(pod::Transform<>::model),
UF_LUA_REGISTER_USERTYPE_DEFINE(move, []( pod::Transform<>& self, sol::variadic_args va ) {
auto it = va.begin();
if ( va.size() == 1 ) {
pod::Vector3f delta = *it++;
self = uf::transform::move( self, delta );
} else if ( va.size() == 2 ) {
pod::Vector3f axis = *it++;
double delta = *it++;
self = uf::transform::move( self, axis, delta );
}
}),
UF_LUA_REGISTER_USERTYPE_DEFINE(rotate, []( pod::Transform<>& self, sol::variadic_args va ) {
auto it = va.begin();
if ( va.size() == 1 ) {
pod::Quaternion<> delta = *it++;
self = uf::transform::rotate( self, delta );
} else if ( va.size() == 2 ) {
pod::Vector3f axis = *it++;
double delta = *it++;
self = uf::transform::rotate( self, axis, delta );
}
})
)

View File

@ -0,0 +1,59 @@
#include <uf/ext/lua/lua.h>
#include <uf/utils/math/vector.h>
UF_LUA_REGISTER_USERTYPE(pod::Vector3f,
sol::call_constructor, sol::initializers(
[]( pod::Vector3f& self, const pod::Vector3f& copy = {} ) {
self = copy;
},
[]( pod::Vector3f& self, float x, float y, float z ) {
self = uf::vector::create(x, y, z);
}
),
UF_LUA_REGISTER_USERTYPE_MEMBER(pod::Vector3f::x),
UF_LUA_REGISTER_USERTYPE_MEMBER(pod::Vector3f::y),
UF_LUA_REGISTER_USERTYPE_MEMBER(pod::Vector3f::z),
UF_LUA_REGISTER_USERTYPE_DEFINE( v, []( pod::Vector3f& self, const size_t& index ) {
return self[index];
}),
UF_LUA_REGISTER_USERTYPE_DEFINE( distance, []( pod::Vector3f& self, const pod::Vector3f& other ) {
return uf::vector::distance( self, other );
}),
UF_LUA_REGISTER_USERTYPE_DEFINE( lerp, []( const pod::Vector3f& start, const pod::Vector3f& end, double delta ) {
return uf::vector::lerp( start, end, delta );
}),
UF_LUA_REGISTER_USERTYPE_DEFINE( __tostring, []( pod::Vector3f& self ) {
std::stringstream ss;
ss << "Vector(" << self.x << ", " << self.y << ", " << self.z << ")";
return ss.str();
})
)
UF_LUA_REGISTER_USERTYPE(pod::Vector4f,
sol::call_constructor, sol::initializers(
[]( pod::Vector4f& self, const pod::Vector4f& copy = {} ) {
self = copy;
},
[]( pod::Vector4f& self, float x, float y, float z, float w ) {
self = uf::vector::create(x, y, z, w);
}
),
UF_LUA_REGISTER_USERTYPE_MEMBER(pod::Vector4f::x),
UF_LUA_REGISTER_USERTYPE_MEMBER(pod::Vector4f::y),
UF_LUA_REGISTER_USERTYPE_MEMBER(pod::Vector4f::z),
UF_LUA_REGISTER_USERTYPE_MEMBER(pod::Vector4f::w),
UF_LUA_REGISTER_USERTYPE_DEFINE( v, []( pod::Vector4f& self, const size_t& index ) {
return self[index];
}),
UF_LUA_REGISTER_USERTYPE_DEFINE( distance, []( pod::Vector4f& self, const pod::Vector4f& other ) {
return uf::vector::distance( self, other );
}),
UF_LUA_REGISTER_USERTYPE_DEFINE( lerp, []( const pod::Vector4f& start, const pod::Vector4f& end, double delta ) {
return uf::vector::lerp( start, end, delta );
}),
UF_LUA_REGISTER_USERTYPE_DEFINE( __tostring, []( pod::Vector4f& self ) {
std::stringstream ss;
ss << "Vector(" << self.x << ", " << self.y << ", " << self.z << ", " << self.w << ")";
return ss.str();
})
)

View File

@ -70,7 +70,7 @@ void UF_API_CALL ext::AL::listener( ALenum name, std::vector<ALfloat> parameters
case 3: alListener3f( name, parameters[0], parameters[1], parameters[2] ); break;
default: alListenerfv( name, &parameters[0] ); break;
}
ext::oal.checkError(__FUNCTION__, __LINE__);
AL_CHECK_ERROR();
}
void UF_API_CALL ext::AL::listener( const std::string string, std::vector<ALfloat> parameters ) {
if ( string == "GAIN" ) return this->listener( AL_GAIN, parameters );
@ -90,12 +90,13 @@ ext::al::Source::~Source() {
void UF_API_CALL ext::al::Source::generate() {
if ( this->m_index ) this->destroy();
alGenSources(1, &this->m_index); ext::oal.checkError(__FUNCTION__, __LINE__);
AL_CHECK_ERROR(alGenSources(1, &this->m_index));
}
void UF_API_CALL ext::al::Source::destroy() {
if ( this->m_index && alIsSource(this->m_index) ) {
if ( this->playing() ) this->stop();
alDeleteSources(1, &this->m_index); ext::oal.checkError(__FUNCTION__, __LINE__);
AL_CHECK_ERROR(alSourcei(this->m_index, AL_BUFFER, 0));
AL_CHECK_ERROR(alDeleteSources(1, &this->m_index));
}
this->m_index = 0;
}
@ -109,7 +110,8 @@ void UF_API_CALL ext::al::Source::source( ALenum name, std::vector<ALfloat> para
case 3: alSource3f( this->m_index, name, parameters[0], parameters[1], parameters[2] ); break;
default: alSourcefv( this->m_index, name, &parameters[0] ); break;
}
ext::oal.checkError(__FUNCTION__, __LINE__, std::to_string(name));
AL_CHECK_ERROR();
//ext::oal.checkError(__FUNCTION__, __LINE__, std::to_string(name));
}
void UF_API_CALL ext::al::Source::source( const std::string string, std::vector<ALfloat> parameters ) {
// alSourcef
@ -137,7 +139,7 @@ void UF_API_CALL ext::al::Source::source( ALenum name, std::vector<ALint> parame
case 3: alSource3i( this->m_index, name, parameters[0], parameters[1], parameters[2] ); break;
default: alSourceiv( this->m_index, name, &parameters[0] ); break;
}
ext::oal.checkError(__FUNCTION__, __LINE__);
AL_CHECK_ERROR();
}
void UF_API_CALL ext::al::Source::source( const std::string string, std::vector<ALint> parameters ) {
// alSourcei
@ -154,13 +156,14 @@ void UF_API_CALL ext::al::Source::source( const std::string string, std::vector<
if ( string == "DIRECTION" ) return this->source( AL_DIRECTION, parameters );
}
void UF_API_CALL ext::al::Source::play() {
alSourcePlay(this->m_index); ext::oal.checkError(__FUNCTION__, __LINE__, std::to_string(this->m_index));
AL_CHECK_ERROR(alSourcePlay(this->m_index));
}
void UF_API_CALL ext::al::Source::stop() {
alSourceStop(this->m_index); ext::oal.checkError(__FUNCTION__, __LINE__, std::to_string(this->m_index));
AL_CHECK_ERROR(alSourceStop(this->m_index));
}
bool UF_API_CALL ext::al::Source::playing() {
ALCenum state; alGetSourcei(this->m_index, AL_SOURCE_STATE, &state);
ALCenum state;
AL_CHECK_ERROR(alGetSourcei(this->m_index, AL_SOURCE_STATE, &state));
return state == AL_PLAYING;
}
@ -173,11 +176,11 @@ ext::al::Buffer::~Buffer() {
void UF_API_CALL ext::al::Buffer::generate() {
if ( this->m_index ) this->destroy();
alGenBuffers(1, &this->m_index); ext::oal.checkError(__FUNCTION__, __LINE__);
AL_CHECK_ERROR(alGenBuffers(1, &this->m_index));
}
void UF_API_CALL ext::al::Buffer::destroy() {
if ( this->m_index && alIsBuffer(this->m_index) ) {
alDeleteBuffers(1, &this->m_index); ext::oal.checkError(__FUNCTION__, __LINE__);
AL_CHECK_ERROR(alDeleteBuffers(1, &this->m_index));
}
this->m_index = 0;
}
@ -186,7 +189,7 @@ ALuint UF_API_CALL ext::al::Buffer::getIndex() const { return this->m_index; }
void UF_API_CALL ext::al::Buffer::buffer(ALenum format, const ALvoid* data, ALsizei size, ALsizei frequency) {
if ( !this->m_index ) this->generate();
alBufferData(this->m_index, format, data, size, frequency); ext::oal.checkError(__FUNCTION__, __LINE__, std::to_string(format) + " @ " + std::to_string(size) + " @ " + std::to_string(frequency));
AL_CHECK_ERROR(alBufferData(this->m_index, format, data, size, frequency));
}

View File

@ -164,7 +164,7 @@ bool ext::openvr::initialize( int stage ) {
if ( DEBUG_MARKER ) std::cout << ext::openvr::driver.manifest << std::endl;
for ( auto i = 0; i < manifest["action_sets"].size(); ++i ) {
if ( DEBUG_MARKER ) std::cout << manifest["action_sets"][i] << std::endl;
std::string name = manifest["action_sets"][i]["name"].asString();
std::string name = manifest["action_sets"][i]["name"].as<std::string>();
vr::VRActionSetHandle_t handle;
VR_CHECK_INPUT_RESULT( vr::VRInput()->GetActionSetHandle( name.c_str(), &handle ) );
handles.actionSets[name] = handle;
@ -172,7 +172,7 @@ bool ext::openvr::initialize( int stage ) {
// handles.actionSets.push_back(handle);
}
for ( auto i = 0; i < manifest["actions"].size(); ++i ) {
std::string name = manifest["actions"][i]["name"].asString();
std::string name = manifest["actions"][i]["name"].as<std::string>();
vr::VRActionHandle_t handle;
VR_CHECK_INPUT_RESULT( vr::VRInput()->GetActionHandle( name.c_str(), &handle ) );
handles.actions[name] = handle;
@ -188,7 +188,7 @@ bool ext::openvr::initialize( int stage ) {
if ( DEBUG_MARKER ) std::cout << "Registered hook for haptic: " << ("VR:Haptics."+split.back()) << std::endl;
uf::hooks.addHook( "VR:Haptics."+split.back(), [&](const std::string& event)->std::string{
uf::Serializer json = event;
if ( vr::VRInputError_None != vr::VRInput()->TriggerHapticVibrationAction( handle, json["delay"].asFloat(), json["duration"].asFloat(), json["frequency"].asFloat(), json["amplitude"].asFloat(), vr::k_ulInvalidInputValueHandle ) )
if ( vr::VRInputError_None != vr::VRInput()->TriggerHapticVibrationAction( handle, json["delay"].as<float>(), json["duration"].as<float>(), json["frequency"].as<float>(), json["amplitude"].as<float>(), vr::k_ulInvalidInputValueHandle ) )
return "false";
return "true";
});

View File

@ -213,9 +213,14 @@ void ext::vulkan::Buffers::updateBuffer( void* data, VkDeviceSize length, Buffer
// assert(buffer.allocationInfo.size == length);
if ( buffer.allocationInfo.size != length ) {
// std::cout << "Mismatch buffer update: " << buffer.allocationInfo.size << " vs " << length << ", resetting for safety..." << std::endl;
if ( true ) {
VK_VALIDATION_MESSAGE("Mismatch buffer update: Requesting " << buffer.allocationInfo.size << ", got " << length);
} else {
length = buffer.allocationInfo.size;
VK_VALIDATION_MESSAGE("Mismatch buffer update: Requesting " << buffer.allocationInfo.size << ", got " << length << ", resetting for safety");
}
uf::iostream << "\n";
// assert(buffer.allocationInfo.size > length);
length = buffer.allocationInfo.size;
}

View File

@ -20,7 +20,7 @@ namespace {
vr::VRCompositor()->GetVulkanInstanceExtensionsRequired( pExtensionStr, nBufferSize );
std::vector<std::string> extensions = uf::string::split( pExtensionStr, " " );
for ( auto& str : extensions ) {
// std::cout << str << std::endl;
// uf::iostream << str << "\n";
requested.push_back(str);
}
// requested.insert( requested.end(), extensions.begin(), extensions.end() );
@ -53,7 +53,7 @@ namespace {
break;
}
if ( !found ) {
std::cout << "Vulkan missing requested extension: " << requestedExtension << std::endl;
uf::iostream << "Vulkan missing requested extension: " << requestedExtension << "\n";
}
}
}
@ -65,8 +65,8 @@ namespace {
if ( feature == #NAME ) {\
if ( device.features.NAME == VK_TRUE ) {\
device.enabledFeatures.NAME = true;\
if ( ext::vulkan::settings::validation ) std::cout << "Enabled feature: " << feature << std::endl;\
} else if ( ext::vulkan::settings::validation ) std::cout << "Failed to enable feature: " << feature << std::endl;\
if ( ext::vulkan::settings::validation ) uf::iostream << "Enabled feature: " << feature << "\n";\
} else if ( ext::vulkan::settings::validation ) uf::iostream << "Failed to enable feature: " << feature << "\n";\
}
for ( auto& feature : ext::vulkan::settings::requestedDeviceFeatures ) {
@ -132,8 +132,8 @@ namespace {
if ( feature == #NAME ) {\
if ( device.features2.NAME == VK_TRUE ) {\
device.enabledFeatures2.NAME = true;\
if ( ext::vulkan::settings::validation ) std::cout << "Enabled feature: " << feature << std::endl;\
} else if ( ext::vulkan::settings::validation ) std::cout << "Failed to enable feature: " << feature << std::endl;\
if ( ext::vulkan::settings::validation ) uf::iostream << "Enabled feature: " << feature << "\n";\
} else if ( ext::vulkan::settings::validation ) uf::iostream << "Failed to enable feature: " << feature << "\n";\
}
#undef CHECK_FEATURE2
}
@ -536,7 +536,7 @@ void ext::vulkan::Device::initialize() {
{
if ( ext::vulkan::settings::validation )
for ( auto ext : requestedExtensions )
std::cout << "Requested instance extension: " << ext << std::endl;
uf::iostream << "Requested instance extension: " << ext << "\n";
uint32_t extensionsCount = 0;
uint32_t enabledExtensionsCount = 0;
@ -552,7 +552,7 @@ void ext::vulkan::Device::initialize() {
std::vector<const char*> instanceExtensions;
for ( auto& s : supportedExtensions.instance ) {
if ( ext::vulkan::settings::validation )
std::cout << "Enabled instance extension: " << s << std::endl;
uf::iostream << "Enabled instance extension: " << s << "\n";
instanceExtensions.push_back( s.c_str() );
}
@ -665,7 +665,7 @@ void ext::vulkan::Device::initialize() {
{
// Allocate enough ExtensionProperties to support all extensions being enabled
if ( ext::vulkan::settings::validation )
for ( auto ext : requestedExtensions ) std::cout << "Requested device extension: " << ext << std::endl;
for ( auto ext : requestedExtensions ) uf::iostream << "Requested device extension: " << ext << "\n";
uint32_t extensionsCount = 0;
uint32_t enabledExtensionsCount = 0;
@ -680,7 +680,7 @@ void ext::vulkan::Device::initialize() {
VK_KHR_SWAPCHAIN_EXTENSION_NAME
};
for ( auto& s : supportedExtensions.device ) {
if ( ext::vulkan::settings::validation ) std::cout << "Enabled device extension: " << s << std::endl;
if ( ext::vulkan::settings::validation ) uf::iostream << "Enabled device extension: " << s << "\n";
deviceExtensions.push_back( s.c_str() );
}
@ -759,7 +759,7 @@ void ext::vulkan::Device::initialize() {
throw std::runtime_error("failed to create logical device!");
if ( ext::vulkan::settings::validation )
std::cout << retrieveDeviceFeatures( *this ) << std::endl;
uf::iostream << retrieveDeviceFeatures( *this ) << "\n";
}
// Create command pool
getCommandPool( QueueEnum::GRAPHICS );

View File

@ -25,7 +25,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st
{
std::ifstream is(this->filename = filename, std::ios::binary | std::ios::in | std::ios::ate);
if ( !is.is_open() ) {
uf::iostream << "Error: Could not open shader file \"" << filename << "\"" << "\n";
VK_DEBUG_MESSAGE("Error: Could not open shader file \"" << filename << "\"");
return;
}
is.seekg(0, std::ios::end); spirv.reserve(is.tellg()); is.seekg(0, std::ios::beg);
@ -66,6 +66,15 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: {
size_t size = comp.get_declared_struct_size(base_type);
if ( size <= 0 ) break;
if ( size > device.properties.limits.maxUniformBufferRange ) {
VK_DEBUG_MESSAGE("Invalid uniform buffer length of " << size << " for shader " << filename);
size = device.properties.limits.maxUniformBufferRange;
}
size_t misalignment = size % device.properties.limits.minStorageBufferOffsetAlignment;
if ( misalignment != 0 ) {
VK_DEBUG_MESSAGE("Invalid uniform buffer alignmnet of " << misalignment << " for shader " << filename << ", correcting...");
size += misalignment;
}
auto& uniform = uniforms.emplace_back();
uniform.create( size );
} break;
@ -82,20 +91,20 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st
if ( !type.array.empty() ) {
size = type.array[0];
/*
std::cout << "ARRAY: " << filename << ":\t";
uf::iostream << "ARRAY: " << filename << ":\t";
for ( auto v : type.array )
std::cout << v << " ";
std::cout << std::endl;
std::cout << "ARRAY: " << filename << ":\t";
uf::iostream << v << " ";
uf::iostream << "\n";
uf::iostream << "ARRAY: " << filename << ":\t";
for ( auto v : type.array_size_literal )
std::cout << v << " ";
std::cout << std::endl;
uf::iostream << v << " ";
uf::iostream << "\n";
*/
}
descriptorSetLayoutBindings.push_back( ext::vulkan::initializers::descriptorSetLayoutBinding( descriptorType, stage, comp.get_decoration(resource.id, spv::DecorationBinding), size ) );
};
// std::cout << "["<<filename<<"] Found resource: "#type " with binding: " << comp.get_decoration(resource.id, spv::DecorationBinding) << std::endl;\
// uf::iostream << "["<<filename<<"] Found resource: "#type " with binding: " << comp.get_decoration(resource.id, spv::DecorationBinding) << "\n";\
#define LOOP_RESOURCES( key, type ) for ( const auto& resource : res.key ) {\
parseResource( resource, type );\
@ -113,6 +122,10 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st
const auto& type = comp.get_type(resource.base_type_id);
size_t size = comp.get_declared_struct_size(type);
if ( size <= 0 ) continue;
if ( size > device.properties.limits.maxPushConstantsSize ) {
VK_DEBUG_MESSAGE("Invalid push constant length of " << size << " for shader " << filename);
size = device.properties.limits.maxPushConstantsSize;
}
auto& pushConstant = pushConstants.emplace_back();
pushConstant.create( size );
}
@ -219,7 +232,7 @@ void ext::vulkan::Pipeline::initialize( Graphic& graphic, GraphicDescriptor& des
this->device = graphic.device;
Device& device = *graphic.device;
// std::cout << &graphic << ": Shaders: " << graphic.material.shaders.size() << " Textures: " << graphic.material.textures.size() << std::endl;
// VK_DEBUG_MESSAGE(&graphic << ": Shaders: " << graphic.material.shaders.size() << " Textures: " << graphic.material.textures.size());
assert( graphic.material.shaders.size() > 0 );
RenderMode& renderMode = ext::vulkan::getRenderMode( descriptor.renderMode, true);
@ -237,8 +250,9 @@ void ext::vulkan::Pipeline::initialize( Graphic& graphic, GraphicDescriptor& des
for ( auto& pushConstant : shader.pushConstants ) {
size_t len = pushConstant.data().len;
if ( len <= 0 || len > device.properties.limits.maxPushConstantsSize ) {
std::cout << "INVALID PUSH CONSTANT LEN OF : " << len << " FOR " << shader.filename << std::endl;
len = 4;
VK_DEBUG_MESSAGE("Invalid push constent length of " << len << " for shader " << shader.filename);
// goto PIPELINE_INITIALIZATION_INVALID;
len = device.properties.limits.maxPushConstantsSize;
}
pushConstantRanges.push_back(ext::vulkan::initializers::pushConstantRange(
shader.descriptor.stage,
@ -348,8 +362,8 @@ void ext::vulkan::Pipeline::initialize( Graphic& graphic, GraphicDescriptor& des
blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD;
blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD;
}
blendAttachmentStates.push_back(blendAttachmentState);
@ -442,6 +456,16 @@ void ext::vulkan::Pipeline::initialize( Graphic& graphic, GraphicDescriptor& des
VK_CHECK_RESULT(vkCreateGraphicsPipelines( device, device.pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipeline));
}
graphic.process = true;
return;
PIPELINE_INITIALIZATION_INVALID:
graphic.process = false;
VK_DEBUG_MESSAGE("Pipeline initialization invalid, updating next tick...");
uf::thread::add( uf::thread::get("Main"), [&]() -> int {
this->initialize( graphic, descriptor );
return 0;}, true );
return;
}
void ext::vulkan::Pipeline::record( Graphic& graphic, VkCommandBuffer commandBuffer ) {
auto bindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
@ -481,68 +505,181 @@ void ext::vulkan::Pipeline::update( Graphic& graphic ) {
return this->update( graphic, graphic.descriptor );
}
void ext::vulkan::Pipeline::update( Graphic& graphic, GraphicDescriptor& descriptor ) {
//
if ( descriptorSet == VK_NULL_HANDLE ) return;
// generate fallback empty texture
auto& emptyTexture = Texture2D::empty;
RenderMode& renderMode = ext::vulkan::getRenderMode(descriptor.renderMode, true);
auto& renderTarget = renderMode.getRenderTarget(descriptor.renderTarget );
std::vector<VkWriteDescriptorSet> writeDescriptorSets;
std::vector<VkDescriptorSetLayoutBinding> descriptorSetLayoutBindings;
std::vector<VkDescriptorImageInfo> inputDescriptors;
std::vector<VkDescriptorImageInfo> imageInfos;
for ( auto& shader : graphic.material.shaders ) {
descriptorSetLayoutBindings.insert( descriptorSetLayoutBindings.begin(), shader.descriptorSetLayoutBindings.begin(), shader.descriptorSetLayoutBindings.end() );
}
struct {
std::vector<VkDescriptorBufferInfo> uniform;
std::vector<VkDescriptorBufferInfo> storage;
std::vector<VkDescriptorImageInfo> image;
std::vector<VkDescriptorImageInfo> sampler;
std::vector<VkDescriptorImageInfo> input;
} infos;
if ( descriptor.subpass < renderTarget.passes.size() ) {
auto& subpass = renderTarget.passes[descriptor.subpass];
for ( auto& input : subpass.inputs ) {
inputDescriptors.push_back(ext::vulkan::initializers::descriptorImageInfo(
infos.input.push_back(ext::vulkan::initializers::descriptorImageInfo(
renderTarget.attachments[input.attachment].view,
// input.layout
input.layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : input.layout
));
}
}
{
for ( auto& texture : graphic.material.textures ) {
infos.image.emplace_back(texture.descriptor);
}
for ( auto& sampler : graphic.material.samplers ) {
infos.sampler.emplace_back(sampler.descriptor.info);
}
}
for ( auto& shader : graphic.material.shaders ) {
#define PARSE_BUFFER( buffers ) for ( auto& buffer : buffers ) {\
if ( buffer.usageFlags & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT ) {\
infos.uniform.emplace_back(buffer.descriptor);\
}\
if ( buffer.usageFlags & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT ) {\
infos.storage.emplace_back(buffer.descriptor);\
}\
}
PARSE_BUFFER(shader.buffers)
PARSE_BUFFER(graphic.buffers)
// check if we can even consume that many infos
size_t consumes = 0;
for ( auto& layout : shader.descriptorSetLayoutBindings ) {
switch ( layout.descriptorType ) {
// consume an texture image info
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
consumes += layout.descriptorCount;
} break;
}
}
for ( size_t i = infos.image.size(); i < consumes; ++i ) {
infos.image.push_back(emptyTexture.descriptor);
}
}
auto uniformBufferInfo = infos.uniform.begin();
auto storageBufferInfo = infos.storage.begin();
auto imageInfo = infos.image.begin();
auto samplerInfo = infos.sampler.begin();
auto inputInfo = infos.input.begin();
#define BREAK_ASSERT(condition, ...) if ( condition ) { VK_DEBUG_MESSAGE(#condition << "\t" << __VA_ARGS__); break; }
std::vector<VkWriteDescriptorSet> writeDescriptorSets;
for ( auto& shader : graphic.material.shaders ) {
for ( auto& layout : shader.descriptorSetLayoutBindings ) {
// VK_DEBUG_MESSAGE(shader.filename << "\tType: " << layout.descriptorType << "\tConsuming: " << layout.descriptorCount);
switch ( layout.descriptorType ) {
// consume an texture image info
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
BREAK_ASSERT( imageInfo == infos.image.end(), "Filename: " << shader.filename << "\tCount: " << layout.descriptorCount )
writeDescriptorSets.push_back(ext::vulkan::initializers::writeDescriptorSet(
descriptorSet,
layout.descriptorType,
layout.binding,
&(*imageInfo),
layout.descriptorCount
));
imageInfo += layout.descriptorCount;
} break;
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: {
BREAK_ASSERT( inputInfo == infos.input.end(), "Filename: " << shader.filename << "\tCount: " << layout.descriptorCount )
writeDescriptorSets.push_back(ext::vulkan::initializers::writeDescriptorSet(
descriptorSet,
layout.descriptorType,
layout.binding,
&(*inputInfo),
layout.descriptorCount
));
inputInfo += layout.descriptorCount;
} break;
case VK_DESCRIPTOR_TYPE_SAMPLER: {
BREAK_ASSERT( samplerInfo == infos.sampler.end(), "Filename: " << shader.filename << "\tCount: " << layout.descriptorCount )
writeDescriptorSets.push_back(ext::vulkan::initializers::writeDescriptorSet(
descriptorSet,
layout.descriptorType,
layout.binding,
&(*samplerInfo),
layout.descriptorCount
));
samplerInfo += layout.descriptorCount;
} break;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: {
BREAK_ASSERT( uniformBufferInfo == infos.uniform.end(), "Filename: " << shader.filename << "\tCount: " << layout.descriptorCount )
writeDescriptorSets.push_back(ext::vulkan::initializers::writeDescriptorSet(
descriptorSet,
layout.descriptorType,
layout.binding,
&(*uniformBufferInfo),
layout.descriptorCount
));
uniformBufferInfo += layout.descriptorCount;
} break;
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: {
BREAK_ASSERT( storageBufferInfo == infos.storage.end(), "Filename: " << shader.filename << "\tCount: " << layout.descriptorCount )
writeDescriptorSets.push_back(ext::vulkan::initializers::writeDescriptorSet(
descriptorSet,
layout.descriptorType,
layout.binding,
&(*storageBufferInfo),
layout.descriptorCount
));
storageBufferInfo += layout.descriptorCount;
} break;
}
}
}
/*
std::vector<VkWriteDescriptorSet> writeDescriptorSets;
std::vector<VkDescriptorImageInfo> imageInfos;
{
for ( auto& shader : graphic.material.shaders ) {
std::vector<VkDescriptorBufferInfo> buffersStorageVector;
std::vector<VkDescriptorBufferInfo> buffersUniformsVector;
for ( auto& buffer : shader.buffers ) {
if ( buffer.usageFlags & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT ) {
auto& descriptor = buffersStorageVector.emplace_back(buffer.descriptor);
if ( descriptor.offset % device->properties.limits.minStorageBufferOffsetAlignment != 0 ) {
// std::cout << "Unaligned offset! Expecting " << device->properties.limits.minUniformBufferOffsetAlignment << ", got " << descriptor.pBufferInfo->offset << std::endl;
descriptor.offset = 0;
}
}
if ( buffer.usageFlags & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT ) {
auto& descriptor = buffersUniformsVector.emplace_back(buffer.descriptor);
if ( descriptor.offset % device->properties.limits.minUniformBufferOffsetAlignment != 0 ) {
// std::cout << "Unaligned offset! Expecting " << device->properties.limits.minUniformBufferOffsetAlignment << ", got " << descriptor.pBufferInfo->offset << std::endl;
descriptor.offset = 0;
}
}
}
for ( auto& buffer : graphic.buffers ) {
if ( buffer.usageFlags & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT ) {
auto& descriptor = buffersStorageVector.emplace_back(buffer.descriptor);
if ( descriptor.offset % device->properties.limits.minStorageBufferOffsetAlignment != 0 ) {
std::cout << "[" << __LINE__ << "] Unaligned offset! Expecting " << device->properties.limits.minUniformBufferOffsetAlignment << ", got " << descriptor.offset << std::endl;
descriptor.offset = 0;
}
}
if ( buffer.usageFlags & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT ) {
auto& descriptor = buffersUniformsVector.emplace_back(buffer.descriptor);
if ( descriptor.offset % device->properties.limits.minUniformBufferOffsetAlignment != 0 ) {
std::cout << "[" << __LINE__ << "] Unaligned offset! Expecting " << device->properties.limits.minUniformBufferOffsetAlignment << ", got " << descriptor.offset << std::endl;
descriptor.offset = 0;
}
}
#define PARSE_BUFFER( buffers ) for ( auto& buffer : buffers ) {\
if ( buffer.usageFlags & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT ) {\
auto& descriptor = buffersStorageVector.emplace_back(buffer.descriptor);\
if ( descriptor.offset % device->properties.limits.minStorageBufferOffsetAlignment != 0 ) {\
VK_DEBUG_MESSAGE("Unaligned offset! Expecting " << device->properties.limits.minUniformBufferOffsetAlignment << ", got " << descriptor.offset);\
goto PIPELINE_UPDATE_INVALID;\
}\
}\
if ( buffer.usageFlags & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT ) {\
auto& descriptor = buffersUniformsVector.emplace_back(buffer.descriptor);\
if ( descriptor.offset % device->properties.limits.minUniformBufferOffsetAlignment != 0 ) {\
VK_DEBUG_MESSAGE("Unaligned offset! Expecting " << device->properties.limits.minUniformBufferOffsetAlignment << ", got " << descriptor.offset);\
goto PIPELINE_UPDATE_INVALID;\
}\
}\
}
PARSE_BUFFER(shader.buffers)
PARSE_BUFFER(graphic.buffers)
auto textures = graphic.material.textures.begin();
auto samplers = graphic.material.samplers.begin();
auto attachments = inputDescriptors.begin();
@ -569,7 +706,7 @@ void ext::vulkan::Pipeline::update( Graphic& graphic, GraphicDescriptor& descrip
if ( d.imageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL )
d.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
} else {
// std::cout << "textures == graphic.material.textures.end()" << std::endl;
// VK_DEBUG_MESSAGE("textures == graphic.material.textures.end()");
}
imageInfos.push_back( d );
}
@ -603,21 +740,17 @@ void ext::vulkan::Pipeline::update( Graphic& graphic, GraphicDescriptor& descrip
} break;
case VK_DESCRIPTOR_TYPE_SAMPLER: {
if ( samplers == graphic.material.samplers.end() ) {
std::cout << "samplers == graphic.material.samplers.end()" << std::endl;
VK_DEBUG_MESSAGE("samplers == graphic.material.samplers.end()");
break;
}
imageInfo = &((samplers++)->descriptor.info);
} break;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: {
if ( buffersUniforms == buffersUniformsVector.end() ) {
std::cout << "buffersUniforms == buffersUniformsVector.end()" << std::endl;
VK_DEBUG_MESSAGE("buffersUniforms == buffersUniformsVector.end()");
break;
}
auto* descriptor = &(*(buffersUniforms++));
if ( descriptor->offset % device->properties.limits.minUniformBufferOffsetAlignment != 0 ) {
std::cout << __LINE__ << ": Unaligned offset! Expecting " << device->properties.limits.minUniformBufferOffsetAlignment << ", got " << descriptor->offset << std::endl;
descriptor->offset = 0;
}
writeDescriptorSets.push_back(ext::vulkan::initializers::writeDescriptorSet(
descriptorSet,
layout.descriptorType,
@ -627,15 +760,10 @@ void ext::vulkan::Pipeline::update( Graphic& graphic, GraphicDescriptor& descrip
} break;
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: {
if ( buffersStorage == buffersStorageVector.end() ) {
std::cout << "buffersStorage == buffersStorageVector.end()" << std::endl;
VK_DEBUG_MESSAGE("buffersStorage == buffersStorageVector.end()");
break;
}
auto* descriptor = &(*(buffersStorage++));
if ( descriptor->offset % device->properties.limits.minStorageBufferOffsetAlignment != 0 ) {
std::cout << __LINE__ << ": Unaligned offset! Expecting " << device->properties.limits.minUniformBufferOffsetAlignment << ", got " << descriptor->offset << std::endl;
descriptor->offset = 0;
}
writeDescriptorSets.push_back(ext::vulkan::initializers::writeDescriptorSet(
descriptorSet,
layout.descriptorType,
@ -645,7 +773,7 @@ void ext::vulkan::Pipeline::update( Graphic& graphic, GraphicDescriptor& descrip
} break;
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: {
if ( attachments == inputDescriptors.end() ) {
std::cout << "attachments == inputDescriptors.end()" << std::endl;
VK_DEBUG_MESSAGE("attachments == inputDescriptors.end()");
break;
}
imageInfo = &(*(attachments++));
@ -673,40 +801,34 @@ void ext::vulkan::Pipeline::update( Graphic& graphic, GraphicDescriptor& descrip
}
}
}
bool invalid = false;
*/
for ( auto& descriptor : writeDescriptorSets ) {
for ( size_t i = 0; i < descriptor.descriptorCount; ++i ) {
if ( descriptor.pBufferInfo ) {
if ( descriptor.pBufferInfo[i].offset % device->properties.limits.minUniformBufferOffsetAlignment != 0 ) {
std::cout << "[" << __LINE__ << "] Invalid descriptor for buffer: " << descriptor.pBufferInfo[i].buffer << " (Offset: " << descriptor.pBufferInfo[i].offset << ", Range: " << descriptor.pBufferInfo[i].range << "), invalidating..." << std::endl;
VK_DEBUG_MESSAGE("Invalid descriptor for buffer: " << descriptor.pBufferInfo[i].buffer << " (Offset: " << descriptor.pBufferInfo[i].offset << ", Range: " << descriptor.pBufferInfo[i].range << "), invalidating...");
goto PIPELINE_UPDATE_INVALID;
/*
auto pointer = const_cast<VkDescriptorBufferInfo*>(&descriptor.pBufferInfo[i]);
pointer->offset = 0;
pointer->range = 0;
pointer->buffer = VK_NULL_HANDLE;
invalid = true;
break;
*/
}
}
/*
if ( descriptor.pImageInfo ) {
if ( descriptor.pImageInfo[i].imageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ) {
// auto pointer = const_cast<VkDescriptorImageInfo*>(&descriptor.pImageInfo[i]);
// pointer->imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
auto pointer = const_cast<VkDescriptorImageInfo*>(&descriptor.pImageInfo[i]);
pointer->imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
}
}
*/
}
}
renderMode.rebuild = true;
if ( invalid ) {
graphic.process = false;
std::cout << "[" << __LINE__ << "] Pipeline invalid, updating next tick..." << std::endl;
uf::thread::add( uf::thread::has("Main") ? uf::thread::get("Main") : uf::thread::create( "Main", false, true ), [&]() -> int {
this->update( graphic, descriptor );
return 0;}, true );
return;
}
graphic.process = true;
vkUpdateDescriptorSets(
@ -716,6 +838,15 @@ void ext::vulkan::Pipeline::update( Graphic& graphic, GraphicDescriptor& descrip
0,
NULL
);
return;
PIPELINE_UPDATE_INVALID:
graphic.process = false;
VK_DEBUG_MESSAGE("Pipeline update invalid, updating next tick...");
uf::thread::add( uf::thread::get("Main"), [&]() -> int {
this->update( graphic, descriptor );
return 0;}, true );
return;
}
void ext::vulkan::Pipeline::destroy() {
if ( aliased ) return;
@ -816,13 +947,14 @@ void ext::vulkan::Graphic::record( VkCommandBuffer commandBuffer ) {
return this->record( commandBuffer, descriptor );
}
void ext::vulkan::Graphic::record( VkCommandBuffer commandBuffer, GraphicDescriptor& descriptor ) {
if ( !process ) return;
if ( !this->hasPipeline( descriptor ) ) {
std::cout << this << ": has no valid pipeline" << std::endl;
VK_DEBUG_MESSAGE(this << ": has no valid pipeline");
return;
}
auto& pipeline = this->getPipeline( descriptor );
if ( pipeline.descriptorSet == VK_NULL_HANDLE ) return;
assert( buffers.size() >= 2 );
Buffer& vertexBuffer = buffers.at(0);
Buffer& indexBuffer = buffers.at(1);
@ -883,6 +1015,6 @@ std::string ext::vulkan::GraphicDescriptor::hash() const {
serializer["depthTest"]["write"] = depthTest.write;
serializer["depthTest"]["operation"] = depthTest.operation;
// if ( renderMode != "Gui" ) std::cout << this << ": " << indices << ": " << renderMode << ": " << subpass << ": " << serializer << std::endl;
// if ( renderMode != "Gui" ) uf::iostream << this << ": " << indices << ": " << renderMode << ": " << subpass << ": " << serializer << "\n";
return uf::string::sha256( serializer.serialize() );
}

View File

@ -35,7 +35,7 @@ void ext::vulkan::RenderMode::createCommandBuffers() {
if ( !graphic.initialized || !graphic.process ) return;
graphics.push_back(&graphic);
};
for ( uf::Scene* scene : ext::vulkan::scenes ) {
for ( uf::Scene* scene : uf::scene::scenes ) {
if ( !scene ) continue;
scene->process(filter);
}
@ -79,7 +79,7 @@ void ext::vulkan::RenderMode::bindPipelines() {
if ( !graphic.process ) return;
graphics.push_back(&graphic);
};
for ( uf::Scene* scene : ext::vulkan::scenes ) {
for ( uf::Scene* scene : uf::scene::scenes ) {
if ( !scene ) continue;
scene->process(filter);
}

View File

@ -50,7 +50,7 @@ void ext::vulkan::ComputeRenderMode::initialize( Device& device ) {
uint32_t eyes = 2;
};
auto* specializationConstants = (SpecializationConstant*) &shader.specializationConstants[0];
specializationConstants->maxLights = metadata["system"]["config"]["engine"]["scenes"]["max lights"].asUInt64();
specializationConstants->maxLights = metadata["system"]["config"]["engine"]["scenes"]["max lights"].as<size_t>();
specializationConstants->eyes = ext::openvr::context ? 2 : 1;
for ( auto& binding : shader.descriptorSetLayoutBindings ) {
if ( binding.descriptorCount > 1 ) {

View File

@ -34,10 +34,10 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
} attachments;
attachments.albedo = renderTarget.attach( VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true ); // albedo
attachments.normals = renderTarget.attach( VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true ); // normals
attachments.normals = renderTarget.attach( VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // normals
if ( !settings::experimental::deferredReconstructPosition )
attachments.position = renderTarget.attach( VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true ); // position
attachments.depth = renderTarget.attach( device.formats.depth, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, true ); // depth
attachments.position = renderTarget.attach( VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // position
attachments.depth = renderTarget.attach( device.formats.depth, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false ); // depth
// attachments.ping = renderTarget.attach( VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ); // albedo
// attachments.pong = renderTarget.attach( VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ); // albedo
@ -144,7 +144,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
uint32_t maxLights = 16;
};
auto* specializationConstants = (SpecializationConstant*) &shader.specializationConstants[0];
specializationConstants->maxLights = metadata["system"]["config"]["engine"]["scenes"]["max lights"].asUInt64();
specializationConstants->maxLights = metadata["system"]["config"]["engine"]["scenes"]["max lights"].as<size_t>();
for ( auto& binding : shader.descriptorSetLayoutBindings ) {
if ( binding.descriptorCount > 1 )
binding.descriptorCount = specializationConstants->maxLights;
@ -152,8 +152,8 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
/*
std::vector<pod::Vector4f> palette;
// size of palette
if ( metadata["system"]["config"]["engine"]["scenes"]["palette"].isNumeric() ) {
size_t size = metadata["system"]["config"]["engine"]["scenes"]["palette"].asUInt64();
if ( metadata["system"]["config"]["engine"]["scenes"]["palette"].is<double>() ) {
size_t size = metadata["system"]["config"]["engine"]["scenes"]["palette"].as<size_t>();
for ( size_t x = 0; x < size; ++x ) {
palette.push_back(pod::Vector4f{
(128.0f + 128.0f * sin(3.1415f * x / 16.0f)) / 256.0f,
@ -163,14 +163,14 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
});
}
// palette array
} else if ( metadata["system"]["config"]["engine"]["scenes"]["palette"].isArray() ) {
} else if ( ext::json::isArray( metadata["system"]["config"]["engine"]["scenes"]["palette"] ) ) {
for ( int i = 0; i < metadata["system"]["config"]["engine"]["scenes"]["palette"].size(); ++i ) {
auto& color = palette.emplace_back();
palette.push_back(pod::Vector4f{
metadata["system"]["config"]["engine"]["scenes"]["palette"][i][0].asFloat(),
metadata["system"]["config"]["engine"]["scenes"]["palette"][i][1].asFloat(),
metadata["system"]["config"]["engine"]["scenes"]["palette"][i][2].asFloat(),
metadata["system"]["config"]["engine"]["scenes"]["palette"][i][3].asFloat(),
metadata["system"]["config"]["engine"]["scenes"]["palette"][i][0].as<float>(),
metadata["system"]["config"]["engine"]["scenes"]["palette"][i][1].as<float>(),
metadata["system"]["config"]["engine"]["scenes"]["palette"][i][2].as<float>(),
metadata["system"]["config"]["engine"]["scenes"]["palette"][i][3].as<float>(),
});
}
}
@ -234,13 +234,13 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ex
for ( auto& attachment : renderTarget.attachments ) {
VkClearValue clearValue;
if ( attachment.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ) {
if ( !metadata["system"]["renderer"]["clear values"][(int) clearValues.size()].isNull() ) {
if ( !ext::json::isNull( metadata["system"]["renderer"]["clear values"][(int) clearValues.size()] ) ) {
auto& v = metadata["system"]["renderer"]["clear values"][(int) clearValues.size()];
clearValue.color = { {
v[0].asFloat(),
v[1].asFloat(),
v[2].asFloat(),
v[3].asFloat(),
v[0].as<float>(),
v[1].as<float>(),
v[2].as<float>(),
v[3].as<float>(),
} };
} else {
clearValue.color = { { 0, 0, 0, 0 } };

View File

@ -121,7 +121,7 @@ void ext::vulkan::MultiviewStereoscopicDeferredRenderMode::initialize( Device& d
uint32_t maxLights = 16;
};
auto* specializationConstants = (SpecializationConstant*) &shader.specializationConstants[0];
specializationConstants->maxLights = metadata["system"]["config"]["engine"]["scenes"]["max lights"].asUInt64();
specializationConstants->maxLights = metadata["system"]["config"]["engine"]["scenes"]["max lights"].as<size_t>();
for ( auto& binding : shader.descriptorSetLayoutBindings ) {
if ( binding.descriptorCount > 1 )
@ -180,13 +180,13 @@ void ext::vulkan::MultiviewStereoscopicDeferredRenderMode::createCommandBuffers(
for ( auto& attachment : renderTarget.attachments ) {
VkClearValue clearValue;
if ( attachment.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ) {
if ( !metadata["system"]["renderer"]["clear values"][(int) clearValues.size()].isNull() ) {
if ( !ext::json::isNull( metadata["system"]["renderer"]["clear values"][(int) clearValues.size()] ) ) {
auto& v = metadata["system"]["renderer"]["clear values"][(int) clearValues.size()];
clearValue.color = { {
v[0].asFloat(),
v[1].asFloat(),
v[2].asFloat(),
v[3].asFloat(),
v[0].as<float>(),
v[1].as<float>(),
v[2].as<float>(),
v[3].as<float>(),
} };
} else {
clearValue.color = { { 0, 0, 0, 0 } };

View File

@ -24,10 +24,10 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
} attachments;
attachments.albedo = renderTarget.attach( VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true ); // albedo
attachments.normals = renderTarget.attach( VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true ); // normals
attachments.normals = renderTarget.attach( VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // normals
if ( !settings::experimental::deferredReconstructPosition )
attachments.position = renderTarget.attach( VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true ); // position
attachments.depth = renderTarget.attach( device.formats.depth, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, true ); // depth
attachments.position = renderTarget.attach( VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // position
attachments.depth = renderTarget.attach( device.formats.depth, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false ); // depth
// Attach swapchain's image as output
if ( !false ) {
attachments.output = renderTarget.attach( device.formats.color, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, true ); // output
@ -49,8 +49,8 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD;
blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD;
}
swapchainAttachment.blendState = blendAttachmentState;

View File

@ -162,13 +162,13 @@ void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) {
int32_t maxLights = 16;
};
auto& specializationConstants = shader.specializationConstants.get<SpecializationConstant>();
specializationConstants.maxLights = metadata["system"]["config"]["engine"]["scenes"]["max lights"].asUInt64();
specializationConstants.maxLights = metadata["system"]["config"]["engine"]["scenes"]["max lights"].as<size_t>();
*/
struct SpecializationConstant {
uint32_t maxLights = 16;
};
auto* specializationConstants = (SpecializationConstant*) &shader.specializationConstants[0];
specializationConstants->maxLights = metadata["system"]["config"]["engine"]["scenes"]["max lights"].asUInt64();
specializationConstants->maxLights = metadata["system"]["config"]["engine"]["scenes"]["max lights"].as<size_t>();
for ( auto& binding : shader.descriptorSetLayoutBindings ) {
if ( binding.descriptorCount > 1 )
@ -252,13 +252,13 @@ void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const st
for ( auto& attachment : renderTarget.attachments ) {
VkClearValue clearValue;
if ( attachment.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ) {
if ( !metadata["system"]["renderer"]["clear values"][(int) clearValues.size()].isNull() ) {
if ( !ext::json::isNull( metadata["system"]["renderer"]["clear values"][(int) clearValues.size()] ) ) {
auto& v = metadata["system"]["renderer"]["clear values"][(int) clearValues.size()];
clearValue.color = { {
v[0].asFloat(),
v[1].asFloat(),
v[2].asFloat(),
v[3].asFloat(),
v[0].as<float>(),
v[1].as<float>(),
v[2].as<float>(),
v[3].as<float>(),
} };
} else {
clearValue.color = { { 0, 0, 0, 0 } };

View File

@ -125,12 +125,36 @@ size_t ext::vulkan::RenderTarget::attach( VkFormat format, VkImageUsageFlags usa
blendEnabled
);
if ( blendEnabled == VK_TRUE ) {
/*
blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD;
blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD;
*/
/*
blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD;
blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD;
blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_DST_ALPHA;
*/
/*
blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD;
blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD;
*/
blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD;
blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD;
}
attachment->blendState = blendAttachmentState;
}

View File

@ -149,7 +149,7 @@ bool ext::vulkan::hasRenderMode( const std::string& name, bool isName ) {
ext::vulkan::RenderMode& ext::vulkan::addRenderMode( ext::vulkan::RenderMode* mode, const std::string& name ) {
mode->name = name;
renderModes.push_back(mode);
std::cout << "Adding RenderMode: " << name << ": " << mode->getType() << std::endl;
if ( ext::vulkan::settings::validation ) uf::iostream << "Adding RenderMode: " << name << ": " << mode->getType() << "\n";
// reorder
ext::vulkan::states::rebuild = true;
return *mode;
@ -170,7 +170,7 @@ ext::vulkan::RenderMode& ext::vulkan::getRenderMode( const std::string& name, bo
}
}
}
// std::cout << "Requesting RenderMode `" << name << "`, got `" << target->getName() << "` (" << target->getType() << ")" << std::endl;
// if ( ext::vulkan::settings::validation ) uf::iostream << "Requesting RenderMode `" << name << "`, got `" << target->getName() << "` (" << target->getType() << ")" << "\n";
return *target;
}
std::vector<ext::vulkan::RenderMode*> ext::vulkan::getRenderModes( const std::string& name, bool isName ) {
@ -181,7 +181,7 @@ std::vector<ext::vulkan::RenderMode*> ext::vulkan::getRenderModes( const std::ve
for ( auto& renderMode: renderModes ) {
if ( ( isName && std::find(names.begin(), names.end(), renderMode->getName()) != names.end() ) || std::find(names.begin(), names.end(), renderMode->getType()) != names.end() ) {
targets.push_back(renderMode);
// std::cout << "Requestings RenderMode `" << name << "`, got `" << renderMode->getName() << "` (" << renderMode->getType() << ")" << std::endl;
// if ( ext::vulkan::settings::validation ) uf::iostream << "Requestings RenderMode `" << name << "`, got `" << renderMode->getName() << "` (" << renderMode->getType() << ")" << "\n";
}
}
return targets;
@ -250,7 +250,7 @@ void ext::vulkan::initialize( uint8_t stage ) {
graphic.initializePipeline();
ext::vulkan::states::rebuild = true;
};
for ( uf::Scene* scene : ext::vulkan::scenes ) {
for ( uf::Scene* scene : uf::scene::scenes ) {
if ( !scene ) continue;
scene->process(filter);
}
@ -297,7 +297,7 @@ void ext::vulkan::tick() {
graphic.initializePipeline();
ext::vulkan::states::rebuild = true;
};
for ( uf::Scene* scene : ext::vulkan::scenes ) {
for ( uf::Scene* scene : uf::scene::scenes ) {
if ( !scene ) continue;
scene->process(filter);
}
@ -350,7 +350,7 @@ void ext::vulkan::render() {
if ( !renderMode ) continue;
if ( !renderMode->execute ) continue;
ext::vulkan::currentRenderMode = renderMode;
for ( uf::Scene* scene : ext::vulkan::scenes ) scene->render();
for ( uf::Scene* scene : uf::scene::scenes ) scene->render();
renderMode->render();
}
@ -371,7 +371,7 @@ void ext::vulkan::destroy() {
uf::Graphic& graphic = entity->getComponent<uf::Graphic>();
graphic.destroy();
};
for ( uf::Scene* scene : ext::vulkan::scenes ) {
for ( uf::Scene* scene : uf::scene::scenes ) {
if ( !scene ) continue;
scene->process(filter);
}
@ -379,7 +379,7 @@ void ext::vulkan::destroy() {
for ( auto& renderMode : renderModes ) {
if ( !renderMode ) continue;
renderMode->destroy();
delete renderMode;
// delete renderMode;
renderMode = NULL;
}

View File

@ -25,8 +25,8 @@ void UF_API_CALL spec::uni::Window::pushEvent( const uf::OptimalHook::name_t& na
void UF_API_CALL spec::uni::Window::pushEvent( const uf::ReadableHook::argument_t& serialized ) {
if ( !uf::hooks.prefersReadable() ) return;
uf::Serializer json = serialized;
if ( !uf::hooks.exists(json["type"].asString()) ) return;
this->m_events.readable.push({json["type"].asString(), serialized});
if ( !uf::hooks.exists(json["type"].as<std::string>()) ) return;
this->m_events.readable.push({json["type"].as<std::string>(), serialized});
}
void UF_API_CALL spec::uni::Window::pushEvent( const uf::OptimalHook::argument_t& userdata ) {
if ( uf::hooks.prefersReadable() ) return;

View File

@ -21,6 +21,9 @@ UF_API uf::Audio::Audio( const uf::Audio& copy ) :
{
}
*/
bool uf::Audio::mute = false;
uf::Audio::~Audio() {
this->destroy();
}
@ -31,6 +34,10 @@ bool UF_API uf::Audio::initialized() {
return true;
}
void UF_API uf::Audio::destroy() {
{
auto filename = this->getFilename();
if ( filename != "" ) std::cout << "Audio::Destroy() Destroying " << filename << std::endl;
}
this->m_source.destroy();
this->m_buffer.destroy();
}
@ -39,10 +46,14 @@ bool UF_API uf::Audio::playing() {
if ( !this->m_source.playing() ) return false;
return true;
}
void UF_API uf::Audio::load( const std::string& filename ) { if ( filename != "" ) this->m_filename = filename;
void UF_API uf::Audio::load( const std::string& filename ) {
if ( uf::Audio::mute ) return;
if ( this->initialized() ) this->destroy();
if ( filename != "" ) this->m_filename = filename;
ALenum format;
ALsizei frequency;
std::vector<char> buffer;
std::string extension = uf::io::extension( this->m_filename );
std::vector<char> buffer; ALenum format; ALsizei frequency;
if ( extension == "ogg" ) {
ext::Vorbis vorbis; vorbis.load( this->m_filename );
@ -50,17 +61,19 @@ void UF_API uf::Audio::load( const std::string& filename ) { if ( filename != ""
format = vorbis.getFormat();
frequency = vorbis.getFrequency();
this->m_duration = vorbis.getDuration();
this->m_buffer.generate(); ext::oal.checkError(__FUNCTION__, __LINE__);
this->m_source.generate(); ext::oal.checkError(__FUNCTION__, __LINE__);
this->m_buffer.buffer( format, &buffer[0], buffer.size(), frequency ); ext::oal.checkError(__FUNCTION__, __LINE__);
this->m_source.source( "BUFFER", std::vector<ALint>{ this->m_buffer.getIndex() } ); ext::oal.checkError(__FUNCTION__, __LINE__);
this->m_source.source( "PITCH", std::vector<ALfloat>{ 1 } ); ext::oal.checkError(__FUNCTION__, __LINE__);
this->m_source.source( "GAIN", std::vector<ALfloat>{ 1 } ); ext::oal.checkError(__FUNCTION__, __LINE__);
this->m_source.source( "LOOPING", std::vector<ALint>{ AL_FALSE } ); ext::oal.checkError(__FUNCTION__, __LINE__);
}
if ( buffer.empty() ) return;
AL_CHECK_ERROR(this->m_buffer.generate());
AL_CHECK_ERROR(this->m_source.generate());
AL_CHECK_ERROR(this->m_buffer.buffer( format, &buffer[0], buffer.size(), frequency ));
AL_CHECK_ERROR(this->m_source.source( "BUFFER", std::vector<ALint>{ this->m_buffer.getIndex() } ));
AL_CHECK_ERROR(this->m_source.source( "PITCH", std::vector<ALfloat>{ 1 } ));
AL_CHECK_ERROR(this->m_source.source( "GAIN", std::vector<ALfloat>{ 1 } ));
AL_CHECK_ERROR(this->m_source.source( "LOOPING", std::vector<ALint>{ AL_FALSE } ));
}
void UF_API uf::Audio::play() {
@ -81,7 +94,7 @@ float uf::Audio::getDuration() const {
ALfloat UF_API uf::Audio::getTime() {
if ( !this->playing() ) return 0;
ALfloat pos;
alGetSourcef(this->m_source.getIndex(), AL_SEC_OFFSET, &pos ); ext::oal.checkError(__FUNCTION__, __LINE__);
AL_CHECK_ERROR(alGetSourcef(this->m_source.getIndex(), AL_SEC_OFFSET, &pos ));
return pos;
}
void UF_API uf::Audio::setTime( ALfloat pos ) {
@ -92,7 +105,7 @@ void UF_API uf::Audio::setTime( ALfloat pos ) {
ALfloat UF_API uf::Audio::getPitch() {
if ( !this->initialized() ) return 0;
ALfloat pitch;
alGetSourcef(this->m_source.getIndex(), AL_PITCH, &pitch ); ext::oal.checkError(__FUNCTION__, __LINE__);
AL_CHECK_ERROR(alGetSourcef(this->m_source.getIndex(), AL_PITCH, &pitch ));
return pitch;
}
void UF_API uf::Audio::setPitch( ALfloat pitch ) {
@ -103,7 +116,7 @@ void UF_API uf::Audio::setPitch( ALfloat pitch ) {
ALfloat UF_API uf::Audio::getGain() {
if ( !this->initialized() ) return 0;
ALfloat gain;
alGetSourcef(this->m_source.getIndex(), AL_GAIN, &gain ); ext::oal.checkError(__FUNCTION__, __LINE__);
AL_CHECK_ERROR(alGetSourcef(this->m_source.getIndex(), AL_GAIN, &gain ));
return gain;
}
void UF_API uf::Audio::setGain( ALfloat gain ) {
@ -114,7 +127,7 @@ void UF_API uf::Audio::setGain( ALfloat gain ) {
ALfloat UF_API uf::Audio::getRolloffFactor() {
if ( !this->initialized() ) return 0;
ALfloat rolloffFactor;
alGetSourcef(this->m_source.getIndex(), AL_ROLLOFF_FACTOR, &rolloffFactor ); ext::oal.checkError(__FUNCTION__, __LINE__);
AL_CHECK_ERROR(alGetSourcef(this->m_source.getIndex(), AL_ROLLOFF_FACTOR, &rolloffFactor ));
return rolloffFactor;
}
void UF_API uf::Audio::setRolloffFactor( ALfloat rolloffFactor ) {
@ -125,7 +138,7 @@ void UF_API uf::Audio::setRolloffFactor( ALfloat rolloffFactor ) {
ALfloat UF_API uf::Audio::getMaxDistance() {
if ( !this->initialized() ) return 0;
ALfloat maxDistance;
alGetSourcef(this->m_source.getIndex(), AL_MAX_DISTANCE, &maxDistance ); ext::oal.checkError(__FUNCTION__, __LINE__);
AL_CHECK_ERROR(alGetSourcef(this->m_source.getIndex(), AL_MAX_DISTANCE, &maxDistance ));
return maxDistance;
}
void UF_API uf::Audio::setMaxDistance( ALfloat maxDistance ) {
@ -146,10 +159,14 @@ void UF_API uf::Audio::setVolume( float volume ) {
}
float UF_API uf::Audio::getVolume() const {
ALfloat pos;
alGetSourcef(this->m_source.getIndex(), AL_GAIN, &pos ); ext::oal.checkError(__FUNCTION__, __LINE__);
AL_CHECK_ERROR(alGetSourcef(this->m_source.getIndex(), AL_GAIN, &pos ));
return pos;
}
uf::SoundEmitter::~SoundEmitter() {
this->cleanup(true);
}
uf::Audio& UF_API uf::SoundEmitter::add( const std::string& filename ) {
if ( this->m_container.find( filename ) != this->m_container.end() ) return this->get(filename);
uf::Audio& sound = this->m_container[filename];
@ -176,7 +193,9 @@ const uf::SoundEmitter::container_t& UF_API uf::SoundEmitter::get() const {
void UF_API uf::SoundEmitter::cleanup( bool purge ) {
for ( auto& pair : this->m_container ) {
if ( !pair.second.playing() ) {
if ( purge || !pair.second.playing() ) {
pair.second.stop();
pair.second.destroy();
this->m_container.erase(pair.first);
}
}

View File

@ -2,17 +2,15 @@
UF_API uf::MemoryPool uf::component::memoryPool;
uf::Component::~Component() {
this->destroyComponents();
}
void uf::Component::destroyComponents() {
for ( auto& kv : this->m_container ) {
pod::Component& component = kv.second;
uf::userdata::destroy(uf::component::memoryPool, component.userdata);
/*
if ( uf::component::memoryPool.size() > 0 ) {
uf::userdata::destroy(uf::component::memoryPool, component.userdata);
} else {
uf::userdata::destroy(component.userdata);
}
*/
}
this->m_container.clear();
}
#include <uf/utils/serialize/serializer.h>

View File

@ -125,20 +125,32 @@ bool uf::HookHandler::isAliasToOptimal( const Readable::alias_t::name_t& name )
}
// Calls a hook in either readable or optimal format (no argument is passed unless it's aliased)
void uf::HookHandler::call( const Readable::name_t& name ) {
if ( !this->exists(name) ) return;
this->call(name, Readable::argument_t());
this->call(name, Optimal::argument_t());
std::vector<uf::HookHandler::Readable::return_t> uf::HookHandler::call( const Readable::name_t& name ) {
struct {
std::vector<uf::HookHandler::Readable::return_t> readable;
std::vector<uf::HookHandler::Optimal::return_t> optimal;
} returns;
if ( !this->exists(name) ) return returns.readable;
returns.readable = this->call(name, Readable::argument_t());
returns.optimal = this->call(name, Optimal::argument_t());
/*
if ( typeid(Readable::return_t) == typeid(Optimal::return_t) ) {
returns.readable.insert( returns.readable.end(), returns.optimal.begin(), returns.optimal.end() );
}
*/
return returns.readable;
}
// Calls a hook in readable format
std::vector<uf::HookHandler::Readable::return_t> uf::HookHandler::call( const Readable::name_t& name, const Readable::argument_t& argument ) {
std::vector<Readable::return_t> returns;
std::vector<uf::HookHandler::Readable::return_t> returns;
if ( !this->exists(name) ) return returns;
if ( !this->isReadable(name) ) {
if ( !this->isAliasToReadable(name) ) return returns;
auto& aliases = this->m_readable.aliases.at(name);
for ( auto& alias : aliases ) {
this->call( alias.name, (argument != "" ? argument : alias.argument) );
auto result = this->call( alias.name, (argument != "" ? argument : alias.argument) );
returns.insert( returns.end(), result.begin(), result.end() );
}
return returns;
}
@ -155,36 +167,25 @@ std::vector<uf::HookHandler::Readable::return_t> uf::HookHandler::call( const Re
return returns;
}
// Calls a hook in optimal format
void uf::HookHandler::call( const Optimal::name_t& name, const Optimal::argument_t& argument ) {
if ( !this->exists(name) ) return;
std::vector<uf::HookHandler::Optimal::return_t> uf::HookHandler::call( const Optimal::name_t& name, const Optimal::argument_t& argument ) {
std::vector<uf::HookHandler::Optimal::return_t> returns;
if ( !this->exists(name) ) return returns;
if ( !this->isOptimal(name) ) {
if ( !this->isAliasToOptimal(name) ) return;
if ( !this->isAliasToOptimal(name) ) return returns;
auto& aliases = this->m_optimal.aliases.at(name);
for ( auto& alias : aliases ) {
this->call( alias.name, (argument ? argument : alias.argument) );
auto result = this->call( alias.name, (argument ? argument : alias.argument) );
returns.insert( returns.end(), result.begin(), result.end() );
}
return;
return returns;
}
auto& hooks = this->m_optimal.hooks.at(name);
for ( auto& hook : hooks ) {
hook( argument );
/*
try {
hook( argument );
} catch ( std::exception& e ) {
uf::iostream << "ERROR: Exception thrown while calling hook `" << name << "`!" << "\n"
<< "\twhat(): " << e.what() << "\n";
// throw;
} catch ( bool handled ) {
if ( !handled ) throw;
} catch ( ... ) {
uf::iostream << "ERROR: Exception thrown while calling hook `" << name << "`!" << "\n"
<< "\twhat(): " << "???" << "\n";
// throw;
}
*/
auto result = hook( argument );
returns.push_back(result);
}
return returns;
}
/*

View File

@ -8,30 +8,54 @@
#include <fstream>
#include <functional>
uf::Serializer::Serializer( const std::string& str ) {
this->deserialize(str);
}
uf::Serializer::Serializer( const Json::Value& json ) {
try {
*this = json;
} catch (...) {
// ignore parse errors
namespace {
std::string encode( const Json::Value& json, bool pretty = true ) {
/*
std::stringstream ss;
if ( pretty ) {
ss << json;
} else {
Json::StreamWriterBuilder builder;
builder["commentStyle"] = "None";
builder["indentation"] = "";
std::unique_ptr<Json::StreamWriter> writer( builder.newStreamWriter() );
writer->write(json, &ss);
}
return ss.str();
*/
Json::FastWriter fast;
Json::StyledWriter styled;
std::string output = pretty ? styled.write(json) : fast.write(json);
if ( output.back() == '\n' ) output.pop_back();
return output;
}
std::string encode( const sol::table& table ) {
return ext::lua::state["json"]["encode"]( table );
}
void decode( Json::Value& json, const std::string& str ) {
Json::Reader reader;
if ( !reader.parse(str, json) ) {
uf::iostream << "JSON Error: " << reader.getFormattedErrorMessages() << "\n";
}
}
}
uf::Serializer::output_t uf::Serializer::serialize() const {
std::stringstream ss;
ss << *this;
return ss.str();
uf::Serializer::Serializer( const std::string& str ) { //: sol::table(ext::lua::state, sol::create) {
this->deserialize(str);
}
uf::Serializer::Serializer( const sol::table& table ) { //: sol::table(ext::lua::state, sol::create) {
this->deserialize( encode( table ) );
}
uf::Serializer::Serializer( const Json::Value& json ) { //: sol::table(ext::lua::state, sol::create) {
this->deserialize( encode( json ) );
}
uf::Serializer::output_t uf::Serializer::serialize( bool pretty ) const {
return encode( *this, pretty );
}
void uf::Serializer::deserialize( const std::string& str ) {
if ( str != "" )
try {
std::stringstream(str) >> *this;
} catch ( const std::exception& e ) {
uf::iostream << "Error: " << e.what() << "\n";
} catch (...) {
// ignore parse errors
}
if ( str == "" ) return;
decode( *this, str );
}
bool uf::Serializer::readFromFile( const std::string& from ) {
@ -68,13 +92,21 @@ bool uf::Serializer::writeToFile( const std::string& to ) const {
}
void uf::Serializer::merge( const uf::Serializer& other, bool priority ) {
if ( !this->isObject() || !other.isObject() ) return;
if ( !ext::json::isObject( *this ) || !ext::json::isObject( other ) ) return;
std::function<void(Json::Value&, const Json::Value&)> update = [&]( Json::Value& a, const Json::Value& b ) {
if ( !b.isObject() ) return;
if ( !ext::json::isObject( b ) ) return;
for ( const auto& key : b.getMemberNames() ) {
if ( !a.isObject() || !priority ) a[key] = b[key];
/*
if ( !ext::json::isObject( a ) || !priority )
a[key] = b[key];
update(a[key], b[key]);
*/
if( a[key].type() == Json::objectValue && b[key].type() == Json::objectValue ) {
update(a[key], b[key]);
}
if ( !priority )
a[key] = b[key];
}
};
@ -92,8 +124,12 @@ uf::Serializer& uf::Serializer::operator=( const std::string& str ) {
this->deserialize(str);
return *this;
}
uf::Serializer& uf::Serializer::operator=( const sol::table& table ) {
this->deserialize( encode( table ) );
return *this;
}
uf::Serializer& uf::Serializer::operator=( const Json::Value& json ) {
Value::operator=(json);
this->deserialize( encode( json ) );
return *this;
}
uf::Serializer& uf::Serializer::operator<<( const std::string& str ) {

View File

@ -15,15 +15,29 @@ std::string UF_API uf::string::uppercase( const std::string& str ) {
std::transform(upper.begin(), upper.end(), upper.begin(), ::toupper);
return upper;
}
std::vector<std::string> UF_API uf::string::split( const std::string& haystack, const std::string& needle ) {
#include <iostream>
std::vector<std::string> UF_API uf::string::split( const std::string& str, const std::string& delim ) {
std::vector<std::string> tokens;
size_t prev = 0, pos = 0;
do {
pos = str.find(delim, prev);
if (pos == std::string::npos) pos = str.length();
std::string token = str.substr(prev, pos-prev);
if (!token.empty()) tokens.push_back(token);
prev = pos + delim.length();
} while (pos < str.length() && prev < str.length());
if ( tokens.empty() ) tokens.emplace_back(str);
return tokens;
/*
std::vector<std::string> cont;
size_t last = 0, next = 0;
while ((next = haystack.find(needle, last)) != std::string::npos) {
cont.push_back(haystack.substr(last, next-last));
while ((next = str.find(needle, last)) != std::string::npos) {
cont.push_back(str.substr(last, next-last));
last = next + 1;
}
cont.push_back( haystack.substr(last) );
cont.push_back( str.substr(last) );
return cont;
*/
}
std::string UF_API uf::string::replace( const std::string& string, const std::string& search, const std::string& replace ) {
std::string result = string;

View File

@ -51,22 +51,29 @@ void UF_API uf::userdata::destroy( pod::Userdata* userdata ) {
*/
}
size_t uf::userdata::size( size_t len, size_t padding ) {
padding = 0;
// return sizeof(pod::Userdata) + len + ( sizeof(uint8_t) * padding );
return sizeof(size_t) + len + ( sizeof(uint8_t) * padding );
}
//
pod::Userdata* UF_API uf::userdata::create( uf::MemoryPool& requestedMemoryPool, std::size_t len, void* data ) {
if ( len <= 0 ) return NULL;
size_t requestedLen = size( len );
// uf::MemoryPool& memoryPool = uf::MemoryPool::global.size() > 0 ? uf::MemoryPool::global : requestedMemoryPool;
#if UF_MEMORYPOOL_INVALID_MALLOC
uf::MemoryPool& memoryPool = requestedMemoryPool.size() > 0 ? requestedMemoryPool : uf::MemoryPool::global;
pod::Userdata* userdata = (pod::Userdata*) memoryPool.alloc( data, sizeof(pod::Userdata) + len );
pod::Userdata* userdata = (pod::Userdata*) memoryPool.alloc( data, requestedLen );
#else
uf::MemoryPool* memoryPool = NULL;
if ( requestedMemoryPool.size() > 0 ) memoryPool = &requestedMemoryPool;
else if ( uf::MemoryPool::global.size() > 0 ) memoryPool = &uf::MemoryPool::global;
pod::Userdata* userdata = NULL;
if ( memoryPool )
userdata = (pod::Userdata*) memoryPool->alloc( data, sizeof(pod::Userdata) + len );
userdata = (pod::Userdata*) memoryPool->alloc( data, requestedLen );
else {
userdata = (pod::Userdata*) operator new( sizeof(pod::Userdata) + len ); // allocate data for the userdata struct, and then some
userdata = (pod::Userdata*) operator new( requestedLen ); // allocate data for the userdata struct, and then some
if ( data ) memcpy( userdata->data, data, len );
else memset( userdata->data, 0, len );
}
@ -75,7 +82,7 @@ pod::Userdata* UF_API uf::userdata::create( uf::MemoryPool& requestedMemoryPool,
return userdata;
/*
if ( uf::userdata::memoryPool.size() > 0 ) {
auto allocation = uf::userdata::memoryPool.allocate( NULL, sizeof(pod::Userdata) + len );
auto allocation = uf::userdata::memoryPool.allocate( NULL, requestedLen );
pod::Userdata* userdata = (pod::Userdata*) allocation.pointer;
if ( data ) memcpy( userdata->data, data, len );
else memset( userdata->data, 0, len );

View File

@ -18,7 +18,7 @@
#include <uf/engine/asset/asset.h>
EXT_BEHAVIOR_REGISTER_CPP(CraetureBehavior)
UF_BEHAVIOR_REGISTER_CPP(ext::CraetureBehavior)
#define this (&self)
void ext::CraetureBehavior::initialize( uf::Object& self ) {
pod::Transform<>& transform = this->getComponent<pod::Transform<>>();
@ -36,11 +36,11 @@ void ext::CraetureBehavior::initialize( uf::Object& self ) {
/* Gravity */ {
if ( metadata["system"]["physics"]["gravity"] != Json::nullValue ) {
physics.linear.acceleration.x = metadata["system"]["physics"]["gravity"][0].asFloat();
physics.linear.acceleration.y = metadata["system"]["physics"]["gravity"][1].asFloat();
physics.linear.acceleration.z = metadata["system"]["physics"]["gravity"][2].asFloat();
physics.linear.acceleration.x = metadata["system"]["physics"]["gravity"][0].as<float>();
physics.linear.acceleration.y = metadata["system"]["physics"]["gravity"][1].as<float>();
physics.linear.acceleration.z = metadata["system"]["physics"]["gravity"][2].as<float>();
}
if ( !metadata["system"]["physics"]["collision"].asBool() ) {
if ( !metadata["system"]["physics"]["collision"].as<bool>() ) {
physics.linear.acceleration.x = 0;
physics.linear.acceleration.y = 0;
physics.linear.acceleration.z = 0;
@ -69,18 +69,18 @@ void ext::CraetureBehavior::initialize( uf::Object& self ) {
this->addHook( "world:Collision.%UID%", [&](const std::string& event)->std::string{
uf::Serializer json = event;
size_t uid = json["uid"].asUInt64();
size_t uid = json["uid"].as<size_t>();
// do not collide with children
// if ( this->findByUid(uid) ) return "false";
pod::Vector3 normal;
float scale = metadata["system"]["physics"]["collision"].asFloat();
float depth = json["depth"].asFloat() * scale;
float scale = metadata["system"]["physics"]["collision"].as<float>();
float depth = json["depth"].as<float>() * scale;
// if ( fabs(depth) < 0.005 ) return "false"; //std::cout << "Collision depth: " << depth << std::endl;
normal.x = json["normal"][0].asFloat();
normal.y = json["normal"][1].asFloat();
normal.z = json["normal"][2].asFloat();
normal.x = json["normal"][0].as<float>();
normal.y = json["normal"][1].as<float>();
normal.z = json["normal"][2].as<float>();
pod::Vector3 correction = normal * depth;
transform.position -= correction;
@ -97,13 +97,13 @@ void ext::CraetureBehavior::initialize( uf::Object& self ) {
uf::Scene& world = uf::scene::getCurrentScene();
uf::Serializer& masterdata = world.getComponent<uf::Serializer>();
std::string filename = json["filename"].asString();
std::string filename = json["filename"].as<std::string>();
if ( uf::io::extension(filename) != "ogg" ) return "false";
if ( filename == "" ) return "false";
uf::Audio& sfx = this->getComponent<uf::SoundEmitter>().add(filename);
sfx.setVolume(masterdata["volumes"]["sfx"].asFloat());
sfx.setVolume(masterdata["volumes"]["sfx"].as<float>());
auto& pTransform = world.getController().getComponent<pod::Transform<>>();
sfx.setPosition( transform.position );
sfx.play();
@ -112,15 +112,15 @@ void ext::CraetureBehavior::initialize( uf::Object& self ) {
});
this->addHook( "world:Craeture.OnHit.%UID%", [&](const std::string& event)->std::string{
uf::Serializer json = event;
uint64_t phase = json["phase"].asUInt64();
uint64_t phase = json["phase"].as<size_t>();
// start color
pod::Vector4f color = { 1, 1, 1, 0 };
if ( phase == 0 ) {
color = pod::Vector4f{
json["color"][0].asFloat(),
json["color"][1].asFloat(),
json["color"][2].asFloat(),
json["color"][3].asFloat(),
json["color"][0].as<float>(),
json["color"][1].as<float>(),
json["color"][2].as<float>(),
json["color"][3].as<float>(),
};
}
metadata["color"][0] = color[0];
@ -128,7 +128,7 @@ void ext::CraetureBehavior::initialize( uf::Object& self ) {
metadata["color"][2] = color[2];
metadata["color"][3] = color[3];
if ( metadata["timers"]["hurt"].asFloat() < timer.elapsed().asDouble() ) {
if ( metadata["timers"]["hurt"].as<float>() < timer.elapsed().asDouble() ) {
metadata["timers"]["hurt"] = timer.elapsed().asDouble() + 1.0f;
uf::Scene& scene = uf::scene::getCurrentScene();
@ -140,7 +140,7 @@ void ext::CraetureBehavior::initialize( uf::Object& self ) {
});
this->addHook( "world:Craeture.Hurt.%UID%", [&](const std::string& event)->std::string{
uf::Serializer json = event;
if ( metadata["timers"]["flash"].asFloat() < timer.elapsed().asDouble() ) {
if ( metadata["timers"]["flash"].as<float>() < timer.elapsed().asDouble() ) {
metadata["timers"]["flash"] = timer.elapsed().asDouble() + 0.4f;
for ( int i = 0; i < 16; ++i ) {
uf::Serializer payload;
@ -162,18 +162,18 @@ void ext::CraetureBehavior::tick( uf::Object& self ) {
uf::Serializer& sMetadata = scene.getComponent<uf::Serializer>();
uf::Serializer& pMetadata = scene.getController().getComponent<uf::Serializer>();
if ( !pMetadata["system"]["control"].asBool() ) return;
if ( !sMetadata["system"]["physics"]["optimizations"]["entity-local update"].asBool() ) return;
if ( !pMetadata["system"]["control"].as<bool>() ) return;
if ( !sMetadata["system"]["physics"]["optimizations"]["entity-local update"].as<bool>() ) return;
pod::Transform<>& transform = this->getComponent<pod::Transform<>>();
pod::Physics& physics = this->getComponent<pod::Physics>();
/* Gravity */ {
if ( metadata["system"]["physics"]["gravity"] != Json::nullValue ) {
physics.linear.acceleration.x = metadata["system"]["physics"]["gravity"][0].asFloat();
physics.linear.acceleration.y = metadata["system"]["physics"]["gravity"][1].asFloat();
physics.linear.acceleration.z = metadata["system"]["physics"]["gravity"][2].asFloat();
physics.linear.acceleration.x = metadata["system"]["physics"]["gravity"][0].as<float>();
physics.linear.acceleration.y = metadata["system"]["physics"]["gravity"][1].as<float>();
physics.linear.acceleration.z = metadata["system"]["physics"]["gravity"][2].as<float>();
}
if ( !metadata["system"]["physics"]["collision"].asBool() ) {
if ( !metadata["system"]["physics"]["collision"].as<bool>() ) {
physics.linear.acceleration.x = 0;
physics.linear.acceleration.y = 0;
physics.linear.acceleration.z = 0;

View File

@ -25,7 +25,7 @@ namespace {
} hands, lines, lights;
}
EXT_BEHAVIOR_REGISTER_CPP(PlayerHandBehavior)
UF_BEHAVIOR_REGISTER_CPP(ext::PlayerHandBehavior)
#define this (&self)
void ext::PlayerHandBehavior::initialize( uf::Object& self ) {
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
@ -46,18 +46,18 @@ void ext::PlayerHandBehavior::initialize( uf::Object& self ) {
{
bool loaded = true;
for ( auto it = metadata["hands"].begin(); it != metadata["hands"].end(); ++it ) {
std::string key = it.key().asString();
if ( !ext::openvr::requestRenderModel(metadata["hands"][key]["controller"]["model"].asString()) ) loaded = false;
std::string key = it.key().as<std::string>();
if ( !ext::openvr::requestRenderModel(metadata["hands"][key]["controller"]["model"].as<std::string>()) ) loaded = false;
}
if ( !loaded ) {
this->addHook( "VR:Model.Loaded", [&](const std::string& event)->std::string{
uf::Serializer json = event;
std::string name = json["name"].asString();
std::string name = json["name"].as<std::string>();
std::string side = "";
if ( name == metadata["hands"]["left"]["controller"]["model"].asString() ) {
if ( name == metadata["hands"]["left"]["controller"]["model"].as<std::string>() ) {
side = "left";
} else if ( name == metadata["hands"]["right"]["controller"]["model"].asString() ) {
} else if ( name == metadata["hands"]["right"]["controller"]["model"].as<std::string>() ) {
side = "right";
};
if ( side == "" ) return "false";
@ -77,22 +77,22 @@ void ext::PlayerHandBehavior::initialize( uf::Object& self ) {
uf::instantiator::bind( "ObjectBehavior", hand );
hand.initialize();
}
if ( metadata["hands"][side]["pointer"]["length"].asFloat() > 0 ) {
if ( metadata["hands"][side]["pointer"]["length"].as<float>() > 0 ) {
line.addAlias<uf::LineMesh, uf::Mesh>();
pod::Transform<>& transform = line.getComponent<pod::Transform<>>();
transform.orientation = uf::quaternion::axisAngle(
{
metadata["hands"][side]["pointer"]["orientation"]["axis"][0].asFloat(),
metadata["hands"][side]["pointer"]["orientation"]["axis"][1].asFloat(),
metadata["hands"][side]["pointer"]["orientation"]["axis"][2].asFloat()
metadata["hands"][side]["pointer"]["orientation"]["axis"][0].as<float>(),
metadata["hands"][side]["pointer"]["orientation"]["axis"][1].as<float>(),
metadata["hands"][side]["pointer"]["orientation"]["axis"][2].as<float>()
},
metadata["hands"][side]["pointer"]["orientation"]["angle"].asFloat() * 3.14159f / 180.0f
metadata["hands"][side]["pointer"]["orientation"]["angle"].as<float>() * 3.14159f / 180.0f
);
transform.position = {
metadata["hands"][side]["pointer"]["offset"][0].asFloat(),
metadata["hands"][side]["pointer"]["offset"][1].asFloat(),
metadata["hands"][side]["pointer"]["offset"][2].asFloat()
metadata["hands"][side]["pointer"]["offset"][0].as<float>(),
metadata["hands"][side]["pointer"]["offset"][1].as<float>(),
metadata["hands"][side]["pointer"]["offset"][2].as<float>()
};
auto& mesh = line.getComponent<uf::LineMesh>();
@ -100,7 +100,7 @@ void ext::PlayerHandBehavior::initialize( uf::Object& self ) {
mesh.vertices = {
{ {0.0f, 0.0f, 0.0f} },
{ {0.0f, 0.0f, metadata["hands"][side]["pointer"]["length"].asFloat()} },
{ {0.0f, 0.0f, metadata["hands"][side]["pointer"]["length"].as<float>()} },
};
graphic.initialize();
graphic.initializeGeometry(mesh);
@ -109,11 +109,11 @@ void ext::PlayerHandBehavior::initialize( uf::Object& self ) {
graphic.material.attachShader("./data/shaders/line.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
graphic.descriptor.topology = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
graphic.descriptor.fill = VK_POLYGON_MODE_LINE;
graphic.descriptor.lineWidth = metadata["hands"][side]["pointer"]["width"].asFloat();
graphic.descriptor.lineWidth = metadata["hands"][side]["pointer"]["width"].as<float>();
line.initialize();
}
if ( metadata["hands"][side]["light"]["should"].asBool() ){
if ( metadata["hands"][side]["light"]["should"].as<bool>() ){
auto& child = hand.loadChild("/light.json", false);
if (side == "left" )
lights.left = &child;
@ -124,11 +124,11 @@ void ext::PlayerHandBehavior::initialize( uf::Object& self ) {
auto& light = side == "left" ? *lights.left : *lights.right;
auto& metadata = light.getComponent<uf::Serializer>();
if ( !json["color"].isNull() ) metadata["light"]["color"] = json["color"];
if ( !json["radius"].isNull() ) metadata["light"]["radius"] = json["radius"];
if ( !json["power"].isNull() ) metadata["light"]["power"] = json["power"];
if ( !json["type"].isNull() ) metadata["light"]["type"] = json["type"];
if ( !json["shadows"].isNull() ) metadata["light"]["shadows"] = json["shadows"];
if ( !ext::json::isNull( json["color"] ) ) metadata["light"]["color"] = json["color"];
if ( !ext::json::isNull( json["radius"] ) ) metadata["light"]["radius"] = json["radius"];
if ( !ext::json::isNull( json["power"] ) ) metadata["light"]["power"] = json["power"];
if ( !ext::json::isNull( json["type"] ) ) metadata["light"]["type"] = json["type"];
if ( !ext::json::isNull( json["shadows"] ) ) metadata["light"]["shadows"] = json["shadows"];
metadata["lights"]["external update"] = true;
// light.initialize();
@ -140,10 +140,10 @@ void ext::PlayerHandBehavior::initialize( uf::Object& self ) {
auto& light = side == "left" ? *lights.left : *lights.right;
auto& metadata = light.getComponent<uf::Serializer>();
if ( !json["color"].isNull() ) metadata["light"]["color"] = json["color"];
if ( !json["radius"].isNull() ) metadata["light"]["radius"] = json["radius"];
if ( !json["power"].isNull() ) metadata["light"]["power"] = json["power"];
if ( !json["shadows"].isNull() ) metadata["light"]["shadows"] = json["shadows"];
if ( !ext::json::isNull( json["color"] ) ) metadata["light"]["color"] = json["color"];
if ( !ext::json::isNull( json["radius"] ) ) metadata["light"]["radius"] = json["radius"];
if ( !ext::json::isNull( json["power"] ) ) metadata["light"]["power"] = json["power"];
if ( !ext::json::isNull( json["shadows"] ) ) metadata["light"]["shadows"] = json["shadows"];
metadata["lights"]["external update"] = true;
light.initialize();
@ -161,22 +161,22 @@ void ext::PlayerHandBehavior::initialize( uf::Object& self ) {
uf::Serializer json = event;
std::string side = &hand == hands.left ? "left" : "right";
if ( json["hand"].asString() != side ) return "false";
if ( json["hand"].as<std::string>() != side ) return "false";
// fire mouse click
if ( json["name"].asString() == "click" ) {
if ( json["name"].as<std::string>() == "click" ) {
uf::Serializer payload;
payload["type"] = "window:Mouse.Click";
payload["invoker"] = "vr";
payload["mouse"]["position"]["x"] = metadata["hands"][side]["cursor"]["position"][0].asFloat();
payload["mouse"]["position"]["y"] = metadata["hands"][side]["cursor"]["position"][1].asFloat();
payload["mouse"]["position"]["x"] = metadata["hands"][side]["cursor"]["position"][0].as<float>();
payload["mouse"]["position"]["y"] = metadata["hands"][side]["cursor"]["position"][1].as<float>();
payload["mouse"]["delta"]["x"] = 0;
payload["mouse"]["delta"]["y"] = 0;
payload["mouse"]["button"] = side == "left" ? "Right" : "Left";
payload["mouse"]["state"] = json["state"].asBool() ? "Down": "Up";
payload["mouse"]["state"] = json["state"].as<bool>() ? "Down": "Up";
uf::hooks.call( payload["type"].asString(), payload );
uf::hooks.call( payload["type"].as<std::string>(), payload );
}
return "true";
@ -186,7 +186,7 @@ void ext::PlayerHandBehavior::initialize( uf::Object& self ) {
std::string side = &hand == hands.left ? "left" : "right";
float mag = json["depth"].asFloat();
float mag = json["depth"].as<float>();
uf::Serializer payload;
payload["delay"] = 0.0f;
payload["duration"] = uf::physics::time::delta;
@ -312,24 +312,24 @@ void ext::PlayerHandBehavior::tick( uf::Object& self ) {
pod::Transform<> gtransform;
pod::Matrix4f mvp;
uf::Serializer& cMetadata = controller.getComponent<uf::Serializer>();
if ( cMetadata["overlay"]["position"].isArray() )
if ( ext::json::isArray( cMetadata["overlay"]["position"] ) )
gtransform.position = {
cMetadata["overlay"]["position"][0].asFloat(),
cMetadata["overlay"]["position"][1].asFloat(),
cMetadata["overlay"]["position"][2].asFloat(),
cMetadata["overlay"]["position"][0].as<float>(),
cMetadata["overlay"]["position"][1].as<float>(),
cMetadata["overlay"]["position"][2].as<float>(),
};
if ( cMetadata["overlay"]["scale"].isArray() )
if ( ext::json::isArray( cMetadata["overlay"]["scale"] ) )
gtransform.scale = {
cMetadata["overlay"]["scale"][0].asFloat(),
cMetadata["overlay"]["scale"][1].asFloat(),
cMetadata["overlay"]["scale"][2].asFloat(),
cMetadata["overlay"]["scale"][0].as<float>(),
cMetadata["overlay"]["scale"][1].as<float>(),
cMetadata["overlay"]["scale"][2].as<float>(),
};
if ( cMetadata["overlay"]["orientation"].isArray() )
if ( ext::json::isArray( cMetadata["overlay"]["orientation"] ) )
gtransform.orientation = {
cMetadata["overlay"]["orientation"][0].asFloat(),
cMetadata["overlay"]["orientation"][1].asFloat(),
cMetadata["overlay"]["orientation"][2].asFloat(),
cMetadata["overlay"]["orientation"][3].asFloat(),
cMetadata["overlay"]["orientation"][0].as<float>(),
cMetadata["overlay"]["orientation"][1].as<float>(),
cMetadata["overlay"]["orientation"][2].as<float>(),
cMetadata["overlay"]["orientation"][3].as<float>(),
};
plane.center = gtransform.position;
@ -390,10 +390,10 @@ void ext::PlayerHandBehavior::render( uf::Object& self ){
uniforms.matrices.view[i] = camera.getView( i );
uniforms.matrices.projection[i] = camera.getProjection( i );
}
uniforms.color[0] = metadata["hands"]["left"]["controller"]["color"][0].asFloat();
uniforms.color[1] = metadata["hands"]["left"]["controller"]["color"][1].asFloat();
uniforms.color[2] = metadata["hands"]["left"]["controller"]["color"][2].asFloat();
uniforms.color[3] = metadata["hands"]["left"]["controller"]["color"][3].asFloat();
uniforms.color[0] = metadata["hands"]["left"]["controller"]["color"][0].as<float>();
uniforms.color[1] = metadata["hands"]["left"]["controller"]["color"][1].as<float>();
uniforms.color[2] = metadata["hands"]["left"]["controller"]["color"][2].as<float>();
uniforms.color[3] = metadata["hands"]["left"]["controller"]["color"][3].as<float>();
// graphic.updateBuffer( uniforms, 0, false );
if ( uf::renderer::currentRenderMode ) {
@ -420,10 +420,10 @@ void ext::PlayerHandBehavior::render( uf::Object& self ){
uniforms.matrices.view[i] = camera.getView( i );
uniforms.matrices.projection[i] = camera.getProjection( i );
}
uniforms.color[0] = metadata["hands"]["right"]["controller"]["color"][0].asFloat();
uniforms.color[1] = metadata["hands"]["right"]["controller"]["color"][1].asFloat();
uniforms.color[2] = metadata["hands"]["right"]["controller"]["color"][2].asFloat();
uniforms.color[3] = metadata["hands"]["right"]["controller"]["color"][3].asFloat();
uniforms.color[0] = metadata["hands"]["right"]["controller"]["color"][0].as<float>();
uniforms.color[1] = metadata["hands"]["right"]["controller"]["color"][1].as<float>();
uniforms.color[2] = metadata["hands"]["right"]["controller"]["color"][2].as<float>();
uniforms.color[3] = metadata["hands"]["right"]["controller"]["color"][3].as<float>();
// graphic.updateBuffer( uniforms, 0, false );
if ( uf::renderer::currentRenderMode ) {
@ -450,10 +450,10 @@ void ext::PlayerHandBehavior::render( uf::Object& self ){
uniforms.matrices.view[i] = camera.getView( i );
uniforms.matrices.projection[i] = camera.getProjection( i );
}
uniforms.color[0] = metadata["hands"]["left"]["pointer"]["color"][0].asFloat();
uniforms.color[1] = metadata["hands"]["left"]["pointer"]["color"][1].asFloat();
uniforms.color[2] = metadata["hands"]["left"]["pointer"]["color"][2].asFloat();
uniforms.color[3] = metadata["hands"]["left"]["pointer"]["color"][3].asFloat();
uniforms.color[0] = metadata["hands"]["left"]["pointer"]["color"][0].as<float>();
uniforms.color[1] = metadata["hands"]["left"]["pointer"]["color"][1].as<float>();
uniforms.color[2] = metadata["hands"]["left"]["pointer"]["color"][2].as<float>();
uniforms.color[3] = metadata["hands"]["left"]["pointer"]["color"][3].as<float>();
// graphic.updateBuffer( uniforms, 0, false );
graphic.material.shaders.front().updateBuffer( uniforms, 0, false );
}
@ -471,10 +471,10 @@ void ext::PlayerHandBehavior::render( uf::Object& self ){
uniforms.matrices.view[i] = camera.getView( i );
uniforms.matrices.projection[i] = camera.getProjection( i );
}
uniforms.color[0] = metadata["hands"]["right"]["pointer"]["color"][0].asFloat();
uniforms.color[1] = metadata["hands"]["right"]["pointer"]["color"][1].asFloat();
uniforms.color[2] = metadata["hands"]["right"]["pointer"]["color"][2].asFloat();
uniforms.color[3] = metadata["hands"]["right"]["pointer"]["color"][3].asFloat();
uniforms.color[0] = metadata["hands"]["right"]["pointer"]["color"][0].as<float>();
uniforms.color[1] = metadata["hands"]["right"]["pointer"]["color"][1].as<float>();
uniforms.color[2] = metadata["hands"]["right"]["pointer"]["color"][2].as<float>();
uniforms.color[3] = metadata["hands"]["right"]["pointer"]["color"][3].as<float>();
// graphic.updateBuffer( uniforms, 0, false );
graphic.material.shaders.front().updateBuffer( uniforms, 0, false );
}

View File

@ -6,7 +6,7 @@
#include <uf/utils/math/physics.h>
#include <uf/utils/camera/camera.h>
EXT_BEHAVIOR_REGISTER_CPP(LightBehavior)
UF_BEHAVIOR_REGISTER_CPP(ext::LightBehavior)
#define this (&self)
void ext::LightBehavior::initialize( uf::Object& self ) {
auto& metadata = this->getComponent<uf::Serializer>();
@ -15,7 +15,7 @@ void ext::LightBehavior::initialize( uf::Object& self ) {
auto& scene = uf::scene::getCurrentScene();
auto& controller = scene.getController();
if ( metadata["light"]["shadows"]["enabled"].asBool() ) {
if ( metadata["light"]["shadows"]["enabled"].as<bool>() ) {
auto& renderMode = this->getComponent<uf::renderer::RenderTargetRenderMode>();
std::string name = "RT:" + std::to_string((int) this->getUid());
uf::renderer::addRenderMode( &renderMode, name );
@ -23,39 +23,39 @@ void ext::LightBehavior::initialize( uf::Object& self ) {
camera = controller.getComponent<uf::Camera>();
camera.getTransform() = {};
camera.setStereoscopic(false);
if ( metadata["light"]["shadows"]["fov"].isNumeric() ) {
camera.setFov( metadata["light"]["shadows"]["fov"].asFloat() );
if ( metadata["light"]["shadows"]["fov"].is<double>() ) {
camera.setFov( metadata["light"]["shadows"]["fov"].as<float>() );
camera.updateProjection();
}
if ( metadata["light"]["radius"].isArray() ) {
if ( ext::json::isArray( metadata["light"]["radius"] ) ) {
auto bounds = camera.getBounds();
bounds.x = metadata["light"]["radius"][0].asFloat();
bounds.y = metadata["light"]["radius"][1].asFloat();
bounds.x = metadata["light"]["radius"][0].as<float>();
bounds.y = metadata["light"]["radius"][1].as<float>();
camera.setBounds(bounds);
}
if ( metadata["light"]["shadows"]["resolution"].isArray() ) {
renderMode.width = metadata["light"]["shadows"]["resolution"][0].asUInt64();
renderMode.height = metadata["light"]["shadows"]["resolution"][1].asUInt64();
if ( ext::json::isArray( metadata["light"]["shadows"]["resolution"] ) ) {
renderMode.width = metadata["light"]["shadows"]["resolution"][0].as<size_t>();
renderMode.height = metadata["light"]["shadows"]["resolution"][1].as<size_t>();
auto size = camera.getSize();
size.x = renderMode.width;
size.y = renderMode.height;
camera.setSize(size);
} else {
renderMode.width = metadata["light"]["shadows"]["resolution"].asUInt64();
renderMode.height = metadata["light"]["shadows"]["resolution"].asUInt64();
renderMode.width = metadata["light"]["shadows"]["resolution"].as<size_t>();
renderMode.height = metadata["light"]["shadows"]["resolution"].as<size_t>();
auto size = camera.getSize();
size.x = renderMode.width;
size.y = renderMode.height;
camera.setSize(size);
}
}
if ( !metadata["light"]["shadows"]["bias"].isNumeric() ) {
if ( !metadata["light"]["shadows"]["bias"].is<double>() ) {
metadata["light"]["shadows"]["bias"] = 0.00005f;
}
if ( !metadata["light"]["color"].isArray() ) {
metadata["light"]["color"][0] = 1; //metadata["light"]["color"]["random"].asBool() ? (rand() % 100) / 100.0 : 1;
metadata["light"]["color"][1] = 1; //metadata["light"]["color"]["random"].asBool() ? (rand() % 100) / 100.0 : 1;
metadata["light"]["color"][2] = 1; //metadata["light"]["color"]["random"].asBool() ? (rand() % 100) / 100.0 : 1;
if ( !ext::json::isArray( metadata["light"]["color"] ) ) {
metadata["light"]["color"][0] = 1; //metadata["light"]["color"]["random"].as<bool>() ? (rand() % 100) / 100.0 : 1;
metadata["light"]["color"][1] = 1; //metadata["light"]["color"]["random"].as<bool>() ? (rand() % 100) / 100.0 : 1;
metadata["light"]["color"][2] = 1; //metadata["light"]["color"]["random"].as<bool>() ? (rand() % 100) / 100.0 : 1;
}
}
void ext::LightBehavior::tick( uf::Object& self ) {
@ -76,40 +76,40 @@ void ext::LightBehavior::tick( uf::Object& self ) {
if ( parentMetadata["system"]["name"] == "Light" ) {
metadata["light"] = parentMetadata["light"];
} else {
if ( metadata["light"]["fade"].isObject() ) {
if ( metadata["light"]["backup"]["power"].isNull() ) {
if ( ext::json::isObject( metadata["light"]["fade"] ) ) {
if ( ext::json::isNull( metadata["light"]["backup"]["power"] ) ) {
metadata["light"]["backup"]["power"] = metadata["light"]["power"];
}
if ( metadata["light"]["backup"]["color"].isNull() ) {
if ( ext::json::isNull( metadata["light"]["backup"]["color"] ) ) {
metadata["light"]["backup"]["color"] = metadata["light"]["color"];
}
// fade towards
int direction = metadata["light"]["fade"]["increment"].asBool() ? 1 : -1;
metadata["light"]["fade"]["timer"] = metadata["light"]["fade"]["timer"].asFloat() + metadata["light"]["fade"]["rate"].asFloat() * uf::physics::time::delta * direction;
int direction = metadata["light"]["fade"]["increment"].as<bool>() ? 1 : -1;
metadata["light"]["fade"]["timer"] = metadata["light"]["fade"]["timer"].as<float>() + metadata["light"]["fade"]["rate"].as<float>() * uf::physics::time::delta * direction;
// 0 .. delta .. 1 .. (1 + timeout * 0.5)
if ( direction == 1 && metadata["light"]["fade"]["timer"].asFloat() >= 0.5f * metadata["light"]["fade"]["timeout"].asFloat() + 1.0f ) {
if ( direction == 1 && metadata["light"]["fade"]["timer"].as<float>() >= 0.5f * metadata["light"]["fade"]["timeout"].as<float>() + 1.0f ) {
metadata["light"]["fade"]["increment"] = false;
} else if ( direction == -1 && metadata["light"]["fade"]["timer"].asFloat() <= -0.5f * metadata["light"]["fade"]["timeout"].asFloat() ) {
} else if ( direction == -1 && metadata["light"]["fade"]["timer"].as<float>() <= -0.5f * metadata["light"]["fade"]["timeout"].as<float>() ) {
metadata["light"]["fade"]["increment"] = true;
}
{
float delta = metadata["light"]["fade"]["timer"].asFloat();
float delta = metadata["light"]["fade"]["timer"].as<float>();
delta = std::clamp( delta, 0.f, 1.f );
if ( metadata["light"]["fade"]["power"].isNumeric() ) {
metadata["light"]["power"] = uf::math::lerp( metadata["light"]["backup"]["power"].asFloat(), metadata["light"]["fade"]["power"].asFloat(), delta );
if ( metadata["light"]["fade"]["power"].is<double>() ) {
metadata["light"]["power"] = uf::math::lerp( metadata["light"]["backup"]["power"].as<float>(), metadata["light"]["fade"]["power"].as<float>(), delta );
}
if ( metadata["light"]["fade"]["color"].isArray() ) {
if ( ext::json::isArray( metadata["light"]["fade"]["color"] ) ) {
pod::Vector3f fadeColor; {
fadeColor.x = metadata["light"]["fade"]["color"][0].asFloat();
fadeColor.y = metadata["light"]["fade"]["color"][1].asFloat();
fadeColor.z = metadata["light"]["fade"]["color"][2].asFloat();
fadeColor.x = metadata["light"]["fade"]["color"][0].as<float>();
fadeColor.y = metadata["light"]["fade"]["color"][1].as<float>();
fadeColor.z = metadata["light"]["fade"]["color"][2].as<float>();
}
pod::Vector3f origColor; {
origColor.x = metadata["light"]["backup"]["color"][0].asFloat();
origColor.y = metadata["light"]["backup"]["color"][1].asFloat();
origColor.z = metadata["light"]["backup"]["color"][2].asFloat();
origColor.x = metadata["light"]["backup"]["color"][0].as<float>();
origColor.y = metadata["light"]["backup"]["color"][1].as<float>();
origColor.z = metadata["light"]["backup"]["color"][2].as<float>();
}
pod::Vector3f color = uf::vector::lerp( origColor, fadeColor, delta );
@ -119,16 +119,16 @@ void ext::LightBehavior::tick( uf::Object& self ) {
}
}
}
if ( metadata["light"]["flicker"].isObject() ) {
if ( ext::json::isObject( metadata["light"]["flicker"] ) ) {
float r = (rand() % 100) / 100.0;
float rate = metadata["light"]["flicker"]["rate"].asFloat();
if ( metadata["light"]["backup"]["power"].isNull() ) {
float rate = metadata["light"]["flicker"]["rate"].as<float>();
if ( ext::json::isNull( metadata["light"]["backup"]["power"] ) ) {
metadata["light"]["backup"]["power"] = metadata["light"]["power"];
}
metadata["light"]["flicker"]["timer"] = metadata["light"]["flicker"]["timer"].asFloat() + uf::physics::time::delta;
if ( metadata["light"]["flicker"]["timer"].asFloat() >= metadata["light"]["flicker"]["timeout"].asFloat() ) {
metadata["light"]["flicker"]["timer"] = metadata["light"]["flicker"]["timer"].as<float>() + uf::physics::time::delta;
if ( metadata["light"]["flicker"]["timer"].as<float>() >= metadata["light"]["flicker"]["timeout"].as<float>() ) {
metadata["light"]["flicker"]["timer"] = 0;
metadata["light"]["power"] = (r > rate) ? metadata["light"]["flicker"]["power"].asFloat() : metadata["light"]["backup"]["power"];
metadata["light"]["power"] = (r > rate) ? metadata["light"]["flicker"]["power"].as<float>() : metadata["light"]["backup"]["power"];
}
}
}
@ -142,7 +142,7 @@ void ext::LightBehavior::tick( uf::Object& self ) {
auto& controllerTransform = scene.getController().getComponent<pod::Transform<>>();
transform.position = controllerTransform.position + controllerCamera.position;
}
if ( metadata["light"]["external update"].isNull() || (!metadata["light"]["external update"].isNull() && !metadata["light"]["external update"].asBool()) ) {
if ( ext::json::isNull( metadata["light"]["external update"] ) || (!ext::json::isNull( metadata["light"]["external update"] ) && !metadata["light"]["external update"].as<bool>()) ) {
auto& camera = this->getComponent<uf::Camera>();
for ( std::size_t i = 0; i < 2; ++i ) {
camera.setView( uf::matrix::inverse( uf::transform::model( transform ) ), i );
@ -151,14 +151,14 @@ void ext::LightBehavior::tick( uf::Object& self ) {
// render every other frame, maybe
if ( false ) {
if ( metadata["system"]["renderer"]["limit rendering"]["limiter"].isNumeric() && this->hasComponent<uf::renderer::RenderTargetRenderMode>() ) {
if ( metadata["system"]["renderer"]["limit rendering"]["limiter"].is<double>() && this->hasComponent<uf::renderer::RenderTargetRenderMode>() ) {
auto& limiterMetadata = metadata["system"]["renderer"]["limit rendering"];
auto& renderMode = this->getComponent<uf::renderer::RenderTargetRenderMode>();
if ( limiterMetadata["timer"].asFloat() > 1.0f / limiterMetadata["limiter"].asFloat() ) {
if ( limiterMetadata["timer"].as<float>() > 1.0f / limiterMetadata["limiter"].as<float>() ) {
limiterMetadata["timer"] = 0;
renderMode.execute = true;
} else {
limiterMetadata["timer"] = limiterMetadata["timer"].asFloat() + uf::physics::time::delta;
limiterMetadata["timer"] = limiterMetadata["timer"].as<float>() + uf::physics::time::delta;
renderMode.execute = false;
}
}

View File

@ -12,10 +12,6 @@
#include <sstream>
#include "../../scenes/worldscape/gui/pause.h"
#include "../../scenes/worldscape/gui/battle.h"
#include "../../scenes/worldscape//.h"
namespace {
uf::Serializer masterTableGet( const std::string& table ) {
uf::Scene& scene = uf::scene::getCurrentScene();
@ -36,7 +32,7 @@ namespace {
}
}
EXT_BEHAVIOR_REGISTER_CPP(PlayerBehavior)
UF_BEHAVIOR_REGISTER_CPP(ext::PlayerBehavior)
#define this (&self)
void ext::PlayerBehavior::initialize( uf::Object& self ) {
this->addComponent<uf::Camera>(); {
@ -61,56 +57,56 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
} settings;
uf::Camera& camera = this->getComponent<uf::Camera>();
settings.mode = metadata["camera"]["ortho"].asBool() ? -1 : 1;
settings.perspective.size.x = metadata["camera"]["settings"]["size"]["x"].asDouble();
settings.perspective.size.y = metadata["camera"]["settings"]["size"]["y"].asDouble();
settings.mode = metadata["camera"]["ortho"].as<bool>() ? -1 : 1;
settings.perspective.size.x = metadata["camera"]["settings"]["size"]["x"].as<double>();
settings.perspective.size.y = metadata["camera"]["settings"]["size"]["y"].as<double>();
camera.setSize(settings.perspective.size);
if ( settings.mode < 0 ) {
settings.ortho.lr.x = metadata["camera"]["settings"]["left"].asDouble();
settings.ortho.lr.y = metadata["camera"]["settings"]["right"].asDouble();
settings.ortho.bt.x = metadata["camera"]["settings"]["bottom"].asDouble();
settings.ortho.bt.y = metadata["camera"]["settings"]["top"].asDouble();
settings.ortho.nf.x = metadata["camera"]["settings"]["near"].asDouble();
settings.ortho.nf.y = metadata["camera"]["settings"]["far"].asDouble();
settings.ortho.lr.x = metadata["camera"]["settings"]["left"].as<double>();
settings.ortho.lr.y = metadata["camera"]["settings"]["right"].as<double>();
settings.ortho.bt.x = metadata["camera"]["settings"]["bottom"].as<double>();
settings.ortho.bt.y = metadata["camera"]["settings"]["top"].as<double>();
settings.ortho.nf.x = metadata["camera"]["settings"]["near"].as<double>();
settings.ortho.nf.y = metadata["camera"]["settings"]["far"].as<double>();
camera.ortho( settings.ortho.lr, settings.ortho.bt, settings.ortho.nf );
} else {
settings.perspective.fov = metadata["camera"]["settings"]["fov"].asDouble();
settings.perspective.bounds.x = metadata["camera"]["settings"]["clip"]["near"].asDouble();
settings.perspective.bounds.y = metadata["camera"]["settings"]["clip"]["far"].asDouble();
settings.perspective.fov = metadata["camera"]["settings"]["fov"].as<double>();
settings.perspective.bounds.x = metadata["camera"]["settings"]["clip"]["near"].as<double>();
settings.perspective.bounds.y = metadata["camera"]["settings"]["clip"]["far"].as<double>();
camera.setFov(settings.perspective.fov);
camera.setBounds(settings.perspective.bounds);
}
camera.setStereoscopic(true);
settings.offset.x = metadata["camera"]["offset"][0].asDouble();
settings.offset.y = metadata["camera"]["offset"][1].asDouble();
settings.offset.z = metadata["camera"]["offset"][2].asDouble();
settings.offset.x = metadata["camera"]["offset"][0].as<double>();
settings.offset.y = metadata["camera"]["offset"][1].as<double>();
settings.offset.z = metadata["camera"]["offset"][2].as<double>();
pod::Transform<>& transform = camera.getTransform();
/* Transform initialization */ {
transform.position.x = metadata["camera"]["position"][0].asDouble();
transform.position.y = metadata["camera"]["position"][1].asDouble();
transform.position.z = metadata["camera"]["position"][2].asDouble();
transform.position.x = metadata["camera"]["position"][0].as<double>();
transform.position.y = metadata["camera"]["position"][1].as<double>();
transform.position.z = metadata["camera"]["position"][2].as<double>();
transform.scale.x = metadata["camera"]["scale"][0].asDouble();
transform.scale.y = metadata["camera"]["scale"][1].asDouble();
transform.scale.z = metadata["camera"]["scale"][2].asDouble();
transform.scale.x = metadata["camera"]["scale"][0].as<double>();
transform.scale.y = metadata["camera"]["scale"][1].as<double>();
transform.scale.z = metadata["camera"]["scale"][2].as<double>();
}
camera.setOffset(settings.offset);
camera.update(true);
// Update viewport
if ( metadata["camera"]["settings"]["size"]["auto"].asBool() ) {
if ( metadata["camera"]["settings"]["size"]["auto"].as<bool>() ) {
this->addHook( "window:Resized", [&](const std::string& event)->std::string{
uf::Serializer json = event;
// Update persistent window sized (size stored to JSON file)
pod::Vector2ui size; {
size.x = json["window"]["size"]["x"].asUInt64();
size.y = json["window"]["size"]["y"].asUInt64();
size.x = json["window"]["size"]["x"].as<size_t>();
size.y = json["window"]["size"]["y"].as<size_t>();
}
/* Update camera's viewport */ {
uf::Camera& camera = this->getComponent<uf::Camera>();
@ -126,7 +122,7 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
this->addHook( "window:Mouse.CursorVisibility", [&](const std::string& event)->std::string{
uf::Serializer json = event;
metadata["system"]["control"] = !json["state"].asBool();
metadata["system"]["control"] = !json["state"].as<bool>();
return "true";
});
@ -137,12 +133,12 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
// discard events sent by os, only trust client now
if ( json["invoker"] != "client" ) return "true";
pod::Vector2i delta = { json["mouse"]["delta"]["x"].asInt(), json["mouse"]["delta"]["y"].asInt() };
pod::Vector2i size = { json["mouse"]["size"]["x"].asInt(), json["mouse"]["size"]["y"].asInt() };
pod::Vector2i delta = { json["mouse"]["delta"]["x"].as<int>(), json["mouse"]["delta"]["y"].as<int>() };
pod::Vector2i size = { json["mouse"]["size"]["x"].as<int>(), json["mouse"]["size"]["y"].as<int>() };
pod::Vector2 relta = { (float) delta.x / size.x, (float) delta.y / size.y };
relta *= 2;
if ( delta.x == 0 && delta.y == 0 ) return "true";
if ( !metadata["system"]["control"].asBool() ) return "true";
if ( !metadata["system"]["control"].as<bool>() ) return "true";
bool updateCamera = false;
uf::Camera& camera = this->getComponent<uf::Camera>();
@ -150,26 +146,26 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
pod::Transform<>& cameraTransform = camera.getTransform();
if ( delta.x != 0 ) {
double current, minima, maxima; {
current = metadata["camera"]["limit"]["current"][0] != Json::nullValue ? metadata["camera"]["limit"]["current"][0].asDouble() : NAN;
minima = metadata["camera"]["limit"]["minima"][0] != Json::nullValue ? metadata["camera"]["limit"]["minima"][0].asDouble() : NAN;
maxima = metadata["camera"]["limit"]["maxima"][0] != Json::nullValue ? metadata["camera"]["limit"]["maxima"][0].asDouble() : NAN;
current = metadata["camera"]["limit"]["current"][0] != Json::nullValue ? metadata["camera"]["limit"]["current"][0].as<double>() : NAN;
minima = metadata["camera"]["limit"]["minima"][0] != Json::nullValue ? metadata["camera"]["limit"]["minima"][0].as<double>() : NAN;
maxima = metadata["camera"]["limit"]["maxima"][0] != Json::nullValue ? metadata["camera"]["limit"]["maxima"][0].as<double>() : NAN;
}
if ( metadata["camera"]["invert"][0].asBool() ) relta.x *= -1;
if ( metadata["camera"]["invert"][0].as<bool>() ) relta.x *= -1;
current += relta.x;
if ( current != current || ( current < maxima && current > minima ) ) uf::transform::rotate( transform, transform.up, relta.x ), updateCamera = true; else current -= relta.x;
if ( metadata["camera"]["limit"]["current"][0] != Json::nullValue ) metadata["camera"]["limit"]["current"][0] = current;
}
if ( delta.y != 0 ) {
double current, minima, maxima; {
current = metadata["camera"]["limit"]["current"][1] != Json::nullValue ? metadata["camera"]["limit"]["current"][1].asDouble() : NAN;
minima = metadata["camera"]["limit"]["minima"][1] != Json::nullValue ? metadata["camera"]["limit"]["minima"][1].asDouble() : NAN;
maxima = metadata["camera"]["limit"]["maxima"][1] != Json::nullValue ? metadata["camera"]["limit"]["maxima"][1].asDouble() : NAN;
current = metadata["camera"]["limit"]["current"][1] != Json::nullValue ? metadata["camera"]["limit"]["current"][1].as<double>() : NAN;
minima = metadata["camera"]["limit"]["minima"][1] != Json::nullValue ? metadata["camera"]["limit"]["minima"][1].as<double>() : NAN;
maxima = metadata["camera"]["limit"]["maxima"][1] != Json::nullValue ? metadata["camera"]["limit"]["maxima"][1].as<double>() : NAN;
}
if ( metadata["camera"]["invert"][1].asBool() ) relta.y *= -1;
if ( metadata["camera"]["invert"][1].as<bool>() ) relta.y *= -1;
current += relta.y;
if ( current != current || ( current < maxima && current > minima ) ) {
uf::transform::rotate( cameraTransform, cameraTransform.right, relta.y );
// uf::transform::rotate( this->m_animation.transforms[metadata["animation"]["names"]["head"].asString()], {0, 0, 0}, -relta.y );
// uf::transform::rotate( this->m_animation.transforms[metadata["animation"]["names"]["head"].as<std::string>()], {0, 0, 0}, -relta.y );
updateCamera = true;
} else current -= relta.y;
if ( metadata["camera"]["limit"]["current"][1] != Json::nullValue ) metadata["camera"]["limit"]["current"][1] = current;
@ -185,7 +181,7 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
for ( auto& member : json[""]["transients"] ) {
if ( member["type"] != "player" ) continue;
std::string id = member["id"].asString();
std::string id = member["id"].as<std::string>();
metadata[""]["transients"][id]["hp"] = member["hp"];
metadata[""]["transients"][id]["mp"] = member["mp"];
}
@ -212,27 +208,27 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
// detect collision against transients, engage in battle
this->addHook( "world:Collision.%UID%", [&](const std::string& event)->std::string{
if ( metadata["system"]["cooldown"].asFloat() > uf::physics::time::current ) return "false";
if ( !metadata["system"]["control"].asBool() ) return "false";
if ( metadata["system"]["cooldown"].as<float>() > uf::physics::time::current ) return "false";
if ( !metadata["system"]["control"].as<bool>() ) return "false";
uf::Serializer json = event;
std::string state = metadata["system"]["state"].asString();
std::string state = metadata["system"]["state"].as<std::string>();
if ( state != "" && state != "null" ) return "false";
uf::Scene& scene = uf::scene::getCurrentScene();
uf::Entity* entity = scene.findByUid(json["entity"].asUInt64());
uf::Entity* entity = scene.findByUid(json["entity"].as<size_t>());
if ( !entity ) return "false";
uf::Serializer& pMetadata = entity->getComponent<uf::Serializer>();
std::string onCollision = pMetadata["system"]["onCollision"].asString();
std::string onCollision = pMetadata["system"]["onCollision"].as<std::string>();
if ( onCollision == "battle" ) {
uf::Serializer payload;
payload["battle"]["enemy"] = pMetadata[""];
payload["battle"]["enemy"]["uid"] = json["entity"].asUInt64();
payload["battle"]["enemy"]["uid"] = json["entity"].as<size_t>();
payload["battle"]["player"] = metadata[""];
payload["battle"]["player"]["uid"] = this->getUid();
payload["battle"]["music"] = pMetadata["music"];
@ -242,7 +238,7 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
if ( !uf::Window::isKeyPressed("E") ) return "false";
uf::Serializer payload;
payload["dialogue"] = pMetadata["dialogue"];
payload["uid"] = json["entity"].asUInt64();
payload["uid"] = json["entity"].as<size_t>();
this->callHook("menu:Dialogue.Start", payload);
}
// metadata["system"]["cooldown"] = uf::physics::time::current + 5;
@ -278,10 +274,10 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
this->addHook( "discord.Activity.Update.%UID%", [&](const std::string& event)->std::string{
uf::Serializer payload;
std::string leaderId = metadata[""]["party"][0].asString();
std::string leaderId = metadata[""]["party"][0].as<std::string>();
uf::Serializer cardData = masterDataGet("Card", leaderId);
uf::Serializer charaData = masterDataGet("Chara", cardData["character_id"].asString());
std::string leader = charaData["name"].asString();
uf::Serializer charaData = masterDataGet("Chara", cardData["character_id"].as<std::string>());
std::string leader = charaData["name"].as<std::string>();
payload["details"] = "Leader: " + leader;
uf::hooks.call( "discord:Activity.Update", payload );
@ -315,19 +311,19 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
} keys;
if ( ext::openvr::context ) {
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Right, "dpadUp" )["state"].asBool() ) keys.forward = true;
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Right, "dpadDown" )["state"].asBool() ) keys.backwards = true;
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Right, "dpadLeft" )["state"].asBool() ) keys.lookLeft = true; // keys.left = true;
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Right, "dpadRight" )["state"].asBool() ) keys.lookRight = true; // keys.right = true;
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Right, "thumbclick" )["state"].asBool() ) keys.running = true;
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Right, "a" )["state"].asBool() ) keys.jump = true;
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Right, "dpadUp" )["state"].as<bool>() ) keys.forward = true;
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Right, "dpadDown" )["state"].as<bool>() ) keys.backwards = true;
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Right, "dpadLeft" )["state"].as<bool>() ) keys.lookLeft = true; // keys.left = true;
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Right, "dpadRight" )["state"].as<bool>() ) keys.lookRight = true; // keys.right = true;
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Right, "thumbclick" )["state"].as<bool>() ) keys.running = true;
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Right, "a" )["state"].as<bool>() ) keys.jump = true;
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Left, "dpadUp" )["state"].asBool() ) keys.forward = true;
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Left, "dpadDown" )["state"].asBool() ) keys.backwards = true;
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Left, "dpadLeft" )["state"].asBool() ) keys.lookLeft = true;
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Left, "dpadRight" )["state"].asBool() ) keys.lookRight = true;
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Left, "thumbclick" )["state"].asBool() ) keys.crouch = true, keys.walk = true;
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Left, "a" )["state"].asBool() ) keys.paused = true;
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Left, "dpadUp" )["state"].as<bool>() ) keys.forward = true;
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Left, "dpadDown" )["state"].as<bool>() ) keys.backwards = true;
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Left, "dpadLeft" )["state"].as<bool>() ) keys.lookLeft = true;
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Left, "dpadRight" )["state"].as<bool>() ) keys.lookRight = true;
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Left, "thumbclick" )["state"].as<bool>() ) keys.crouch = true, keys.walk = true;
if ( ext::openvr::controllerState( vr::Controller_Hand::Hand_Left, "a" )["state"].as<bool>() ) keys.paused = true;
}
struct {
@ -339,8 +335,8 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
std::string menu = "";
} stats;
stats.floored = physics.linear.velocity.y == 0;
stats.menu = metadata["system"]["menu"].asString();
stats.impulse = metadata["system"]["physics"]["impulse"].asBool();
stats.menu = metadata["system"]["menu"].as<std::string>();
stats.impulse = metadata["system"]["physics"]["impulse"].as<bool>();
struct {
float move = 4;
float walk = 1;
@ -348,12 +344,12 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
float rotate = uf::physics::time::delta;
float limitSquared = 4*4;
} speed; {
speed.rotate *= metadata["system"]["physics"]["rotate"].asFloat();
speed.move = metadata["system"]["physics"]["move"].asFloat();
speed.run = metadata["system"]["physics"]["run"].asFloat() / metadata["system"]["physics"]["move"].asFloat();
speed.walk = metadata["system"]["physics"]["walk"].asFloat() / metadata["system"]["physics"]["move"].asFloat();
speed.rotate *= metadata["system"]["physics"]["rotate"].as<float>();
speed.move = metadata["system"]["physics"]["move"].as<float>();
speed.run = metadata["system"]["physics"]["run"].as<float>() / metadata["system"]["physics"]["move"].as<float>();
speed.walk = metadata["system"]["physics"]["walk"].as<float>() / metadata["system"]["physics"]["move"].as<float>();
}
if ( !metadata["system"]["physics"]["collision"].asBool() ) {
if ( !metadata["system"]["physics"]["collision"].as<bool>() ) {
stats.impulse = true;
}
@ -362,15 +358,15 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
if ( keys.vee ) {
if ( timer.elapsed().asDouble() >= 0.25 ) {
timer.reset();
if ( metadata["system"]["physics"]["backup"]["collision"].isNull() )
if ( ext::json::isNull( metadata["system"]["physics"]["backup"]["collision"] ) )
metadata["system"]["physics"]["backup"]["collision"] = metadata["system"]["physics"]["collision"];
if ( !metadata["system"]["physics"]["collision"].asBool() ) {
if ( !metadata["system"]["physics"]["collision"].as<bool>() ) {
metadata["system"]["physics"]["collision"] = metadata["system"]["physics"]["backup"]["collision"];
} else {
metadata["system"]["physics"]["collision"] = 0;
}
std::cout << "Toggling noclip: " << transform.position.x << ", " << transform.position.y << ", " << transform.position.z << std::endl;
// metadata["system"]["physics"]["collision"] = !metadata["system"]["physics"]["collision"].asBool();
// metadata["system"]["physics"]["collision"] = !metadata["system"]["physics"]["collision"].as<bool>();
physics.linear.velocity = {0,0,0};
}
}
@ -387,7 +383,7 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
metadata["system"]["control"] = false;
uf::hooks.call("menu:Pause");
}
else if ( !metadata["system"]["control"].asBool() ) {
else if ( !metadata["system"]["control"].as<bool>() ) {
stats.menu = "menu";
} else if ( stats.menu == "" ) {
metadata["system"]["control"] = true;
@ -396,19 +392,19 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
}
metadata["system"]["menu"] = stats.menu;
if ( metadata["system"]["physics"]["clamp"].isObject() ) {
if ( metadata["system"]["physics"]["clamp"]["x"].isArray() ) {
transform.position.x = std::clamp( transform.position.x, metadata["system"]["physics"]["clamp"]["x"][0].asFloat(), metadata["system"]["physics"]["clamp"]["x"][1].asFloat() );
if ( ext::json::isObject( metadata["system"]["physics"]["clamp"] ) ) {
if ( ext::json::isArray( metadata["system"]["physics"]["clamp"]["x"] ) ) {
transform.position.x = std::clamp( transform.position.x, metadata["system"]["physics"]["clamp"]["x"][0].as<float>(), metadata["system"]["physics"]["clamp"]["x"][1].as<float>() );
}
if ( metadata["system"]["physics"]["clamp"]["y"].isArray() ) {
transform.position.y = std::clamp( transform.position.y, metadata["system"]["physics"]["clamp"]["y"][0].asFloat(), metadata["system"]["physics"]["clamp"]["y"][1].asFloat() );
if ( ext::json::isArray( metadata["system"]["physics"]["clamp"]["y"] ) ) {
transform.position.y = std::clamp( transform.position.y, metadata["system"]["physics"]["clamp"]["y"][0].as<float>(), metadata["system"]["physics"]["clamp"]["y"][1].as<float>() );
}
if ( metadata["system"]["physics"]["clamp"]["z"].isArray() ) {
transform.position.z = std::clamp( transform.position.z, metadata["system"]["physics"]["clamp"]["z"][0].asFloat(), metadata["system"]["physics"]["clamp"]["z"][1].asFloat() );
if ( ext::json::isArray( metadata["system"]["physics"]["clamp"]["z"] ) ) {
transform.position.z = std::clamp( transform.position.z, metadata["system"]["physics"]["clamp"]["z"][0].as<float>(), metadata["system"]["physics"]["clamp"]["z"][1].as<float>() );
}
}
if ( metadata["system"]["control"].asBool() ) {
if ( metadata["system"]["control"].as<bool>() ) {
if ( stats.floored ) {
pod::Transform<> translator = transform;
if ( ext::openvr::context ) {
@ -463,14 +459,14 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
stats.updateCamera = (stats.walking = true);
}
if ( keys.jump ) {
if ( !metadata["system"]["physics"]["collision"].asBool() ) {
if ( metadata["system"]["physics"]["jump"][0].asFloat() != 0 ) transform.position.x += metadata["system"]["physics"]["jump"][0].asFloat() * uf::physics::time::delta;
if ( metadata["system"]["physics"]["jump"][1].asFloat() != 0 ) transform.position.y += metadata["system"]["physics"]["jump"][1].asFloat() * uf::physics::time::delta;
if ( metadata["system"]["physics"]["jump"][2].asFloat() != 0 ) transform.position.z += metadata["system"]["physics"]["jump"][2].asFloat() * uf::physics::time::delta;
if ( !metadata["system"]["physics"]["collision"].as<bool>() ) {
if ( metadata["system"]["physics"]["jump"][0].as<float>() != 0 ) transform.position.x += metadata["system"]["physics"]["jump"][0].as<float>() * uf::physics::time::delta;
if ( metadata["system"]["physics"]["jump"][1].as<float>() != 0 ) transform.position.y += metadata["system"]["physics"]["jump"][1].as<float>() * uf::physics::time::delta;
if ( metadata["system"]["physics"]["jump"][2].as<float>() != 0 ) transform.position.z += metadata["system"]["physics"]["jump"][2].as<float>() * uf::physics::time::delta;
} else {
if ( metadata["system"]["physics"]["jump"][0].asFloat() != 0 ) physics.linear.velocity.x = metadata["system"]["physics"]["jump"][0].asFloat();
if ( metadata["system"]["physics"]["jump"][1].asFloat() != 0 ) physics.linear.velocity.y = metadata["system"]["physics"]["jump"][1].asFloat();
if ( metadata["system"]["physics"]["jump"][2].asFloat() != 0 ) physics.linear.velocity.z = metadata["system"]["physics"]["jump"][2].asFloat();
if ( metadata["system"]["physics"]["jump"][0].as<float>() != 0 ) physics.linear.velocity.x = metadata["system"]["physics"]["jump"][0].as<float>();
if ( metadata["system"]["physics"]["jump"][1].as<float>() != 0 ) physics.linear.velocity.y = metadata["system"]["physics"]["jump"][1].as<float>();
if ( metadata["system"]["physics"]["jump"][2].as<float>() != 0 ) physics.linear.velocity.z = metadata["system"]["physics"]["jump"][2].as<float>();
}
}
}
@ -483,22 +479,22 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
}
if ( keys.crouch ) {
if ( !metadata["system"]["physics"]["collision"].asBool() ) {
if ( metadata["system"]["physics"]["jump"][0].asFloat() != 0 ) transform.position.x -= metadata["system"]["physics"]["jump"][0].asFloat() * uf::physics::time::delta;
if ( metadata["system"]["physics"]["jump"][1].asFloat() != 0 ) transform.position.y -= metadata["system"]["physics"]["jump"][1].asFloat() * uf::physics::time::delta;
if ( metadata["system"]["physics"]["jump"][2].asFloat() != 0 ) transform.position.z -= metadata["system"]["physics"]["jump"][2].asFloat() * uf::physics::time::delta;
if ( !metadata["system"]["physics"]["collision"].as<bool>() ) {
if ( metadata["system"]["physics"]["jump"][0].as<float>() != 0 ) transform.position.x -= metadata["system"]["physics"]["jump"][0].as<float>() * uf::physics::time::delta;
if ( metadata["system"]["physics"]["jump"][1].as<float>() != 0 ) transform.position.y -= metadata["system"]["physics"]["jump"][1].as<float>() * uf::physics::time::delta;
if ( metadata["system"]["physics"]["jump"][2].as<float>() != 0 ) transform.position.z -= metadata["system"]["physics"]["jump"][2].as<float>() * uf::physics::time::delta;
} else {
if ( !metadata["system"]["crouching"].asBool() ) stats.deltaCrouch = true;
if ( !metadata["system"]["crouching"].as<bool>() ) stats.deltaCrouch = true;
metadata["system"]["crouching"] = true;
}
} else {
if ( metadata["system"]["crouching"].asBool() ) stats.deltaCrouch = true;
if ( metadata["system"]["crouching"].as<bool>() ) stats.deltaCrouch = true;
metadata["system"]["crouching"] = false;
}
}
if ( stats.deltaCrouch ) {
float delta = metadata["system"]["physics"]["crouch"].asFloat();
if ( metadata["system"]["crouching"].asBool() ) camera.getTransform().position.y -= delta;
float delta = metadata["system"]["physics"]["crouch"].as<float>();
if ( metadata["system"]["crouching"].as<bool>() ) camera.getTransform().position.y -= delta;
else camera.getTransform().position.y += delta;
stats.updateCamera = true;
}
@ -507,17 +503,17 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
if ( stats.walking ) {
uf::SoundEmitter& emitter = this->getComponent<uf::SoundEmitter>();
int cycle = rand() % metadata["audio"]["footstep"]["list"].size();
std::string filename = metadata["audio"]["footstep"]["list"][cycle].asString();
std::string filename = metadata["audio"]["footstep"]["list"][cycle].as<std::string>();
uf::Audio& footstep = emitter.add(filename);
bool playing = false;
for ( uint i = 0; i < metadata["audio"]["footstep"]["list"].size(); ++i ) {
uf::Audio& audio = emitter.add(metadata["audio"]["footstep"]["list"][i].asString());
uf::Audio& audio = emitter.add(metadata["audio"]["footstep"]["list"][i].as<std::string>());
if ( audio.playing() ) playing = true;
}
if ( !playing ) {
footstep.play();
footstep.setVolume(metadata["audio"]["footstep"]["volume"].asFloat());
footstep.setVolume(metadata["audio"]["footstep"]["volume"].as<float>());
footstep.setPosition( transform.position );
// [0, 1]

View File

@ -16,8 +16,8 @@
#include <uf/utils/renderer/renderer.h>
EXT_BEHAVIOR_REGISTER_CPP(PortalsBehavior)
EXT_BEHAVIOR_REGISTER_AS_OBJECT(PortalsBehavior, Portals)
UF_BEHAVIOR_REGISTER_CPP(ext::PortalsBehavior)
UF_BEHAVIOR_REGISTER_AS_OBJECT(ext::PortalsBehavior, Portals)
#define this (&self)
void ext::PortalsBehavior::initialize( uf::Object& self ) {
auto& metadata = this->getComponent<uf::Serializer>();
@ -43,8 +43,8 @@ void ext::PortalsBehavior::render( uf::Object& self ){}
void ext::PortalsBehavior::destroy( uf::Object& self ){}
#undef this
EXT_BEHAVIOR_REGISTER_CPP(PortalBehavior)
EXT_BEHAVIOR_REGISTER_AS_OBJECT(PortalBehavior, Portal)
UF_BEHAVIOR_REGISTER_CPP(ext::PortalBehavior)
UF_BEHAVIOR_REGISTER_AS_OBJECT(ext::PortalBehavior, Portal)
#define this (&self)
void ext::PortalBehavior::initialize( uf::Object& self ) {
auto& metadata = this->getComponent<uf::Serializer>();
@ -97,7 +97,7 @@ void ext::PortalBehavior::tick( uf::Object& self ) {
{
auto& conCamera = controller.getComponent<uf::Camera>();
auto& prtTransform = this->getComponent<pod::Transform<>>();
auto& otherSideTransform = this->getParent().findByUid( metadata["target"].asUInt() )->getComponent<pod::Transform<>>();
auto& otherSideTransform = this->getParent().findByUid( metadata["target"].as<size_t>() )->getComponent<pod::Transform<>>();
for ( std::size_t i = 0; i < 2; ++i ) {
pod::Matrix4f controllerCameraToWorldMatrix = uf::matrix::inverse( conCamera.getView(i) );

View File

@ -24,7 +24,7 @@
#include "../../ext.h"
#include "../../gui/gui.h"
EXT_BEHAVIOR_REGISTER_CPP(ExtSceneBehavior)
UF_BEHAVIOR_REGISTER_CPP(ext::ExtSceneBehavior)
#define this ((uf::Scene*) &self)
void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
uf::Asset& assetLoader = this->getComponent<uf::Asset>();
@ -41,8 +41,8 @@ void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
if ( metadata["previous bgm"]["filename"] == "" ) return "false";
std::string filename = metadata["previous bgm"]["filename"].asString();
float timestamp = metadata["previous bgm"]["timestamp"].asFloat();
std::string filename = metadata["previous bgm"]["filename"].as<std::string>();
float timestamp = metadata["previous bgm"]["timestamp"].as<float>();
// std::cout << metadata["previous bgm"] << std::endl;
@ -53,7 +53,7 @@ void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
audio.stop();
}
audio.load(filename);
audio.setVolume(metadata["volumes"]["bgm"].asFloat());
audio.setVolume(metadata["volumes"]["bgm"].as<float>());
audio.setTime(timestamp);
audio.play();
@ -61,7 +61,7 @@ void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
});
this->addHook( "asset:Load.%UID%", [&](const std::string& event)->std::string{
uf::Serializer json = event;
std::string filename = json["filename"].asString();
std::string filename = json["filename"].as<std::string>();
if ( uf::io::extension(filename) != "ogg" ) return "false";
const uf::Audio* audioPointer = NULL;
@ -72,7 +72,7 @@ void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
if ( audio.playing() ) audio.stop();
audio.load(filename);
audio.setVolume(metadata["volumes"]["bgm"].asFloat());
audio.setVolume(metadata["volumes"]["bgm"].as<float>());
audio.play();
return "true";
@ -88,8 +88,8 @@ void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
uf::Object* manager = (uf::Object*) this->globalFindByName("Gui Manager");
if ( !manager ) return "false";
uf::Serializer payload;
// uf::Object* gui = (uf::Object*) manager->findByUid( (payload["uid"] = manager->loadChildUid("/scenes/worldscape/gui/pause/menu.json", false)).asUInt64() );
uf::Object& gui = manager->loadChild("/scenes/worldscape/gui/pause/menu.json", false);
std::string config = metadata["menus"]["pause"].is<std::string>() ? metadata["menus"]["pause"].as<std::string>() : "/scenes/worldscape/gui/pause/menu.json";
uf::Object& gui = manager->loadChild(config, false);
payload["uid"] = gui.getUid();
uf::Serializer& metadata = gui.getComponent<uf::Serializer>();
@ -101,13 +101,22 @@ void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
this->addHook( "world:Entity.LoadAsset", [&](const std::string& event)->std::string{
uf::Serializer json = event;
std::string asset = json["asset"].asString();
std::string uid = json["uid"].asString();
std::string asset = json["asset"].as<std::string>();
std::string uid = json["uid"].as<std::string>();
assetLoader.load(asset, "asset:Load." + uid);
return "true";
});
this->addHook( "shader:Update.%UID%", [&](const std::string& event)->std::string{
uf::Serializer json = event;
json["mode"] = json["mode"].as<size_t>() | metadata["system"]["renderer"]["shader"]["mode"].as<size_t>();
metadata["system"]["renderer"]["shader"]["mode"] = json["mode"];
metadata["system"]["renderer"]["shader"]["parameters"] = json["parameters"];
return "true";
});
/* store viewport size */ {
metadata["system"]["window"]["size"]["x"] = uf::renderer::settings::width;
metadata["system"]["window"]["size"]["y"] = uf::renderer::settings::height;
@ -118,8 +127,8 @@ void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
uf::Serializer json = event;
pod::Vector2ui size; {
size.x = json["window"]["size"]["x"].asUInt64();
size.y = json["window"]["size"]["y"].asUInt64();
size.x = json["window"]["size"]["x"].as<size_t>();
size.y = json["window"]["size"]["y"].as<size_t>();
}
metadata["system"]["window"] = json["system"]["window"];
@ -141,8 +150,9 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
uf::Asset& assetLoader = this->getComponent<uf::Asset>();
/* check if audio needs to loop */ try {
uf::Audio& bgm = this->getComponent<uf::Audio>();
/* check if audio needs to loop */ {
/*
auto& bgm = this->getComponent<uf::Audio>();
float current = bgm.getTime();
float end = bgm.getDuration();
float epsilon = 0.005f;
@ -151,15 +161,14 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
std::string filename = bgm.getFilename();
filename = assetLoader.getOriginal(filename);
if ( filename.find("_intro") != std::string::npos ) {
assetLoader.load(uf::string::replace( filename, "_intro", "" ), "asset:Load." + std::to_string(this->getUid()));
assetLoader.load(uf::string::replace( filename, "_intro", "" ), this->formatHookName("asset:Load.%UID%"));
// loop
} else {
bgm.setTime(0);
if ( !bgm.playing() ) bgm.play();
}
}
} catch ( ... ) {
*/
}
/* Regain control if nothing requests it */ {
@ -180,15 +189,15 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
static uf::Timer<long long> timer(false);
if ( !timer.running() ) timer.start();
if ( uf::Window::isKeyPressed("U") && timer.elapsed().asDouble() >= 1 ) { timer.reset();
auto& allocations = uf::Entity::memoryPool.allocations();
uf::iostream << "Current size: " << allocations.size() << "\n"; //" | UIDs: " << uf::Entity::uids << "\n";
uint orphans = 0;
uint empty = 0;
auto& allocations = uf::Entity::memoryPool.allocations();
uf::iostream << "Current size: " << allocations.size() << "\n"; //" | UIDs: " << uf::Entity::uids << "\n";
for ( auto& allocation : allocations ) {
uf::Entity* e = (uf::Entity*) allocation.pointer;
if ( !e->hasParent() ) {
if ( !e->hasParent() && e != this ) {
++orphans;
uf::iostream << "Orphan: " << e->getName() << ": " << e << "\n";
uf::iostream << "Orphan: " << e->getName() << ": " << e->getUid() << ": " << e << "\n";
}
}
uf::iostream << "Orphans: " << orphans << "\n";
@ -212,7 +221,7 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
}
if ( uf::scene::getCurrentScene().getUid() == this->getUid() ) {
/* Update lights */ if ( metadata["light"]["should"].asBool() ) {
/* Update lights */ if ( metadata["light"]["should"].as<bool>() ) {
// if ( !uf::renderer::currentRenderMode || uf::renderer::currentRenderMode->name != "" ) return;
auto& scene = uf::scene::getCurrentScene();
@ -294,7 +303,7 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
{
uf::Serializer& metadata = controller.getComponent<uf::Serializer>();
if ( metadata["light"]["should"].asBool() ) entities.push_back(&controller);
if ( metadata["light"]["should"].as<bool>() ) entities.push_back(&controller);
}
}
for ( size_t _ = 0; _ < blitters.size(); ++_ ) {
@ -321,30 +330,30 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
uniforms->matrices.projection[i] = camera.getProjection( i );
}
{
uniforms->ambient.x = metadata["light"]["ambient"][0].asFloat();
uniforms->ambient.y = metadata["light"]["ambient"][1].asFloat();
uniforms->ambient.z = metadata["light"]["ambient"][2].asFloat();
uniforms->ambient.w = metadata["light"]["kexp"].asFloat();
uniforms->ambient.x = metadata["light"]["ambient"][0].as<float>();
uniforms->ambient.y = metadata["light"]["ambient"][1].as<float>();
uniforms->ambient.z = metadata["light"]["ambient"][2].as<float>();
uniforms->ambient.w = metadata["light"]["kexp"].as<float>();
}
{
uniforms->fog.color.x = metadata["light"]["fog"]["color"][0].asFloat();
uniforms->fog.color.y = metadata["light"]["fog"]["color"][1].asFloat();
uniforms->fog.color.z = metadata["light"]["fog"]["color"][2].asFloat();
uniforms->fog.color.x = metadata["light"]["fog"]["color"][0].as<float>();
uniforms->fog.color.y = metadata["light"]["fog"]["color"][1].as<float>();
uniforms->fog.color.z = metadata["light"]["fog"]["color"][2].as<float>();
uniforms->fog.range.x = metadata["light"]["fog"]["range"][0].asFloat();
uniforms->fog.range.y = metadata["light"]["fog"]["range"][1].asFloat();
uniforms->fog.range.x = metadata["light"]["fog"]["range"][0].as<float>();
uniforms->fog.range.y = metadata["light"]["fog"]["range"][1].as<float>();
}
{
uniforms->mode.type.x = metadata["system"]["renderer"]["shader"]["mode"].asUInt();
uniforms->mode.type.y = metadata["system"]["renderer"]["shader"]["scalar"].asUInt();
uniforms->mode.parameters.x = metadata["system"]["renderer"]["shader"]["parameters"][0].asFloat();
uniforms->mode.parameters.y = metadata["system"]["renderer"]["shader"]["parameters"][1].asFloat();
uniforms->mode.parameters.z = metadata["system"]["renderer"]["shader"]["parameters"][2].asFloat();
uniforms->mode.type.x = metadata["system"]["renderer"]["shader"]["mode"].as<size_t>();
uniforms->mode.type.y = metadata["system"]["renderer"]["shader"]["scalar"].as<size_t>();
uniforms->mode.parameters.x = metadata["system"]["renderer"]["shader"]["parameters"][0].as<float>();
uniforms->mode.parameters.y = metadata["system"]["renderer"]["shader"]["parameters"][1].as<float>();
uniforms->mode.parameters.z = metadata["system"]["renderer"]["shader"]["parameters"][2].as<float>();
if ( metadata["system"]["renderer"]["shader"]["parameters"][3].asString() == "time" ) {
if ( metadata["system"]["renderer"]["shader"]["parameters"][3].as<std::string>() == "time" ) {
uniforms->mode.parameters.w = uf::physics::time::current;
} else {
uniforms->mode.parameters.w = metadata["system"]["renderer"]["shader"]["parameters"][3].asFloat();
uniforms->mode.parameters.w = metadata["system"]["renderer"]["shader"]["parameters"][3].as<float>();
}
}
{
@ -380,16 +389,16 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
if ( entity == &controller ) light.position.y += 2;
light.position.w = metadata["light"]["radius"][1].asFloat();
light.position.w = metadata["light"]["radius"][1].as<float>();
light.color.x = metadata["light"]["color"][0].asFloat();
light.color.y = metadata["light"]["color"][1].asFloat();
light.color.z = metadata["light"]["color"][2].asFloat();
light.color.x = metadata["light"]["color"][0].as<float>();
light.color.y = metadata["light"]["color"][1].as<float>();
light.color.z = metadata["light"]["color"][2].as<float>();
light.color.w = metadata["light"]["power"].asFloat();
light.color.w = metadata["light"]["power"].as<float>();
light.type = metadata["light"]["type"].asUInt64();
light.depthBias = metadata["light"]["shadows"]["bias"].asFloat();
light.type = metadata["light"]["type"].as<size_t>();
light.depthBias = metadata["light"]["shadows"]["bias"].as<float>();
if ( !hasCompute && entity->hasComponent<uf::renderer::RenderTargetRenderMode>() ) {
auto& renderMode = entity->getComponent<uf::renderer::RenderTargetRenderMode>();

View File

@ -22,7 +22,7 @@
#include <mutex>
EXT_BEHAVIOR_REGISTER_CPP(SceneCollisionBehavior)
UF_BEHAVIOR_REGISTER_CPP(ext::SceneCollisionBehavior)
#define this ((uf::Scene*) &self)
void ext::SceneCollisionBehavior::initialize( uf::Object& self ) {
@ -35,18 +35,18 @@ void ext::SceneCollisionBehavior::tick( uf::Object& self ) {
auto& metadata = this->getComponent<uf::Serializer>();
if ( !metadata["system"]["physics"]["collision"].asBool() ) return;
if ( !metadata["system"]["physics"]["collision"].as<bool>() ) return;
auto& mutex = *(this->getComponent<std::mutex*>());
mutex.lock();
bool threaded = !metadata["system"]["physics"]["single threaded"].asBool();
bool sort = metadata["system"]["physics"]["sort"].asBool();
bool useStrongest = metadata["system"]["physics"]["use"]["strongest"].asBool();
bool queued = metadata["system"]["physics"]["use"]["queue"].asBool();
bool updatePhysics = !metadata["system"]["physics"]["optimizations"]["entity-local update"].asBool();
bool ignoreStaticEntities = metadata["system"]["physics"]["optimizations"]["ignore static entities"].asBool();
bool ignoreDuplicateTests = metadata["system"]["physics"]["optimizations"]["ignore duplicate tests"].asBool();
bool useWorkers = metadata["system"]["physics"]["use"]["worker"].asBool();
bool threaded = !metadata["system"]["physics"]["single threaded"].as<bool>();
bool sort = metadata["system"]["physics"]["sort"].as<bool>();
bool useStrongest = metadata["system"]["physics"]["use"]["strongest"].as<bool>();
bool queued = metadata["system"]["physics"]["use"]["queue"].as<bool>();
bool updatePhysics = !metadata["system"]["physics"]["optimizations"]["entity-local update"].as<bool>();
bool ignoreStaticEntities = metadata["system"]["physics"]["optimizations"]["ignore static entities"].as<bool>();
bool ignoreDuplicateTests = metadata["system"]["physics"]["optimizations"]["ignore duplicate tests"].as<bool>();
bool useWorkers = metadata["system"]["physics"]["use"]["worker"].as<bool>();
pod::Thread& thread = uf::thread::has("Physics") ? uf::thread::get("Physics") : uf::thread::create( "Physics", true, false );
auto function = [&]() -> int {
std::vector<uf::Object*> entities;
@ -58,11 +58,11 @@ void ext::SceneCollisionBehavior::tick( uf::Object& self ) {
auto& transform = entity->getComponent<pod::Transform<>>();
auto& physics = entity->getComponent<pod::Physics>();
if ( metadata["system"]["physics"]["gravity"] != Json::nullValue ) {
physics.linear.acceleration.x = metadata["system"]["physics"]["gravity"][0].asFloat();
physics.linear.acceleration.y = metadata["system"]["physics"]["gravity"][1].asFloat();
physics.linear.acceleration.z = metadata["system"]["physics"]["gravity"][2].asFloat();
physics.linear.acceleration.x = metadata["system"]["physics"]["gravity"][0].as<float>();
physics.linear.acceleration.y = metadata["system"]["physics"]["gravity"][1].as<float>();
physics.linear.acceleration.z = metadata["system"]["physics"]["gravity"][2].as<float>();
}
if ( !metadata["system"]["physics"]["collision"].asBool() ) {
if ( !metadata["system"]["physics"]["collision"].as<bool>() ) {
physics.linear.acceleration.x = 0;
physics.linear.acceleration.y = 0;
physics.linear.acceleration.z = 0;
@ -73,14 +73,17 @@ void ext::SceneCollisionBehavior::tick( uf::Object& self ) {
}
{
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
if ( !entity ) return;
auto& metadata = entity->getComponent<uf::Serializer>();
if ( !metadata["system"]["physics"]["collision"].isNull() && !metadata["system"]["physics"]["collision"].asBool() ) return;
if ( !ext::json::isNull( metadata["system"]["physics"]["collision"] ) && !metadata["system"]["physics"]["collision"].as<bool>() ) return;
if ( entity->hasComponent<uf::Collider>() )
entities.push_back((uf::Object*) entity);
};
this->process(filter);
}
auto onCollision = []( pod::Collider::Manifold& manifold, uf::Object* a, uf::Object* b, bool queued ){
auto onCollision = []( pod::Collider::Manifold& manifold, uf::Object* a, uf::Object* b, bool queued ){
if ( !a || !b ) return;
uf::Serializer payload;
payload["normal"][0] = manifold.normal.x;
payload["normal"][1] = manifold.normal.y;

View File

@ -8,7 +8,7 @@
#include <mutex>
EXT_BEHAVIOR_REGISTER_CPP(SoundEmitterBehavior)
UF_BEHAVIOR_REGISTER_CPP(ext::SoundEmitterBehavior)
#define this ((uf::Scene*) &self)
void ext::SoundEmitterBehavior::initialize( uf::Object& self ) {
@ -21,7 +21,7 @@ void ext::SoundEmitterBehavior::initialize( uf::Object& self ) {
this->addHook( "asset:Load.%UID%", [&](const std::string& event)->std::string{
uf::Serializer json = event;
std::string filename = json["filename"].asString();
std::string filename = json["filename"].as<std::string>();
if ( uf::io::extension(filename) != "ogg" ) return "false";
const uf::Audio* audioPointer = NULL;
@ -31,20 +31,20 @@ void ext::SoundEmitterBehavior::initialize( uf::Object& self ) {
uf::Audio& audio = this->getComponent<uf::Audio>(); //emitter.add(filename);
audio.load(filename);
{
float volume = metadata["audio"]["volume"].isNumeric() ? metadata["audio"]["volume"].asFloat() : sMetadata["volumes"]["sfx"].asFloat();
float volume = metadata["audio"]["volume"].is<double>() ? metadata["audio"]["volume"].as<float>() : sMetadata["volumes"]["sfx"].as<float>();
audio.setVolume(volume);
}
if ( metadata["audio"]["pitch"].isNumeric() ) {
audio.setPitch(metadata["audio"]["pitch"].asFloat());
if ( metadata["audio"]["pitch"].is<double>() ) {
audio.setPitch(metadata["audio"]["pitch"].as<float>());
}
if ( metadata["audio"]["gain"].isNumeric() ) {
audio.setGain(metadata["audio"]["gain"].asFloat());
if ( metadata["audio"]["gain"].is<double>() ) {
audio.setGain(metadata["audio"]["gain"].as<float>());
}
if ( metadata["audio"]["rolloffFactor"].isNumeric() ) {
audio.setRolloffFactor(metadata["audio"]["rolloffFactor"].asFloat());
if ( metadata["audio"]["rolloffFactor"].is<double>() ) {
audio.setRolloffFactor(metadata["audio"]["rolloffFactor"].as<float>());
}
if ( metadata["audio"]["maxDistance"].isNumeric() ) {
audio.setMaxDistance(metadata["audio"]["maxDistance"].asFloat());
if ( metadata["audio"]["maxDistance"].is<double>() ) {
audio.setMaxDistance(metadata["audio"]["maxDistance"].as<float>());
}
audio.play();
@ -63,7 +63,7 @@ void ext::SoundEmitterBehavior::tick( uf::Object& self ) {
audio.setPosition( transform.position );
audio.setOrientation( transform.orientation );
if ( metadata["audio"]["loop"].asBool() ) {
if ( metadata["audio"]["loop"].as<bool>() ) {
float current = audio.getTime();
float end = audio.getDuration();
float epsilon = 0.005f;

View File

@ -33,7 +33,7 @@ namespace {
}
}
EXT_BEHAVIOR_REGISTER_CPP(HousamoSpriteBehavior)
UF_BEHAVIOR_REGISTER_CPP(ext::HousamoSpriteBehavior)
#define this (&self)
void ext::HousamoSpriteBehavior::initialize( uf::Object& self ) {
uf::Scene& scene = uf::scene::getCurrentScene();
@ -43,7 +43,7 @@ void ext::HousamoSpriteBehavior::initialize( uf::Object& self ) {
this->addHook( "graphics:Assign.%UID%", [&](const std::string& event)->std::string{
uf::Serializer json = event;
std::string filename = json["filename"].asString();
std::string filename = json["filename"].as<std::string>();
metadata["system"]["control"] = false;
if ( uf::io::extension(filename) != "png" ) return "false";
@ -92,17 +92,17 @@ void ext::HousamoSpriteBehavior::initialize( uf::Object& self ) {
});
{
std::string id = metadata[""]["party"][0].asString();
std::string id = metadata[""]["party"][0].as<std::string>();
uf::Serializer member = metadata[""]["transients"][id];
uf::Serializer cardData = masterDataGet("Card", id);
std::string name = cardData["filename"].asString();
if ( member["skin"].isString() ) name += "_" + member["skin"].asString();
std::string name = cardData["filename"].as<std::string>();
if ( member["skin"].is<std::string>() ) name += "_" + member["skin"].as<std::string>();
std::string filename = "https://cdn..xyz//unity/Android/fg/fg_" + name + ".png";
if ( cardData["internal"].asBool() ) {
if ( cardData["internal"].as<bool>() ) {
filename = "./data/smtsamo/fg/fg_" + name + ".png";
}
metadata["orientation"] = cardData["orientation"].asString() == "" ? "portrait" : "landscape";
metadata["orientation"] = cardData["orientation"].as<std::string>() == "" ? "portrait" : "landscape";
assetLoader.load(filename, "asset:Load." + std::to_string(this->getUid()) );
}
@ -110,7 +110,7 @@ void ext::HousamoSpriteBehavior::initialize( uf::Object& self ) {
void ext::HousamoSpriteBehavior::tick( uf::Object& self ) {}
void ext::HousamoSpriteBehavior::render( uf::Object& self ){
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
if ( !metadata["system"]["loaded"].asBool() ) return;
if ( !metadata["system"]["loaded"].as<bool>() ) return;
/* Update uniforms */ if ( this->hasComponent<uf::Graphic>() ) {
auto& mesh = this->getComponent<uf::Mesh>();
@ -126,10 +126,10 @@ void ext::HousamoSpriteBehavior::render( uf::Object& self ){
uniforms.matrices.projection[i] = camera.getProjection( i );
}
uniforms.color[0] = metadata["color"][0].asFloat();
uniforms.color[1] = metadata["color"][1].asFloat();
uniforms.color[2] = metadata["color"][2].asFloat();
uniforms.color[3] = metadata["color"][3].asFloat();
uniforms.color[0] = metadata["color"][0].as<float>();
uniforms.color[1] = metadata["color"][1].as<float>();
uniforms.color[2] = metadata["color"][2].as<float>();
uniforms.color[3] = metadata["color"][3].as<float>();
graphic.material.shaders.front().updateBuffer( uniforms, 0, false );
};
}

View File

@ -1,74 +0,0 @@
#include "behavior.h"
#include <uf/utils/serialize/serializer.h>
#include <uf/utils/audio/audio.h>
#include <uf/utils/math/transform.h>
#include <uf/utils/string/ext.h>
#include <uf/engine/asset/asset.h>
EXT_BEHAVIOR_REGISTER_CPP(StaticEmitterBehavior)
#define this ((uf::Object*) &self)
void ext::StaticEmitterBehavior::initialize( uf::Object& self ) {
auto& metadata = this->getComponent<uf::Serializer>();
if ( metadata["distance"].asBool() ) {
// this->addHook( "system:Load.Finished.%UID%", [&](const std::string& event)->std::string{
// uf::Serializer json = event;
auto* hud = this->loadChildPointer("/hud.json", true);
metadata["hud"]["uid"] = hud->getUid();
// return "true";
// });
}
}
void ext::StaticEmitterBehavior::tick( uf::Object& self ) {
auto& scene = uf::scene::getCurrentScene();
auto& controller = scene.getController();
auto& cTransform = controller.getComponent<pod::Transform<>>();
auto& transform = this->getComponent<pod::Transform<>>();
float distanceSquared = uf::vector::distanceSquared( transform.position, cTransform.position );
auto& metadata = this->getComponent<uf::Serializer>();
auto& sMetadata = scene.getComponent<uf::Serializer>();
if ( metadata["static"]["scale"].isNumeric() ) {
distanceSquared *= metadata["static"]["scale"].asFloat();
}
{
float lo = metadata["static"]["range"][0].isNumeric() ? metadata["static"]["range"][0].asFloat() : 0.1f;
float hi = metadata["static"]["range"][1].isNumeric() ? metadata["static"]["range"][1].asFloat() : 0.5f;
float staticBlend = std::clamp( distanceSquared > 1 ? 1.0f / distanceSquared : 1.0f, lo, hi );
float flicker = metadata["static"]["flicker"].isNumeric() ? metadata["static"]["flicker"].asFloat() : 0.001;
float pieces = metadata["static"]["pieces"].isNumeric() ? metadata["static"]["pieces"].asFloat() : 1000;
uint32_t mode = sMetadata["system"]["renderer"]["shader"]["mode"].asUInt();
mode |= (0x1 << 1);
sMetadata["system"]["renderer"]["shader"]["mode"] = mode;
sMetadata["system"]["renderer"]["shader"]["parameters"][0] = flicker;
sMetadata["system"]["renderer"]["shader"]["parameters"][1] = pieces;
sMetadata["system"]["renderer"]["shader"]["parameters"][2] = staticBlend;
sMetadata["system"]["renderer"]["shader"]["parameters"][3] = "time";
}
static uf::Timer<long long> timer(false);
if ( !timer.running() ) timer.start();
if ( metadata["hud"]["uid"].isNumeric() && timer.elapsed().asDouble() > 0.125 ) {
timer.reset();
auto* hud = this->findByUid( metadata["hud"]["uid"].asUInt64() );
auto& hMetadata = hud->getComponent<uf::Serializer>();
double d = uf::vector::distance( cTransform.position, transform.position );
std::string string = uf::string::si( d, "m" );
hMetadata["text settings"]["alpha"] = 0.5f;
if ( hMetadata["text settings"]["string"].asString() != string ) {
uf::Serializer payload;
payload["string"] = string;
hud->as<uf::Object>().callHook("gui:UpdateString.%UID%", payload);
}
}
}
void ext::StaticEmitterBehavior::render( uf::Object& self ){}
void ext::StaticEmitterBehavior::destroy( uf::Object& self ){}
#undef this

View File

@ -1,17 +0,0 @@
#pragma once
#include <uf/config.h>
#include <uf/ext/ext.h>
#include <uf/engine/entity/entity.h>
#include <uf/engine/scene/scene.h>
namespace ext {
class EXT_API StaticEmitterBehavior {
public:
static void attach( uf::Object& );
static void initialize( uf::Object& );
static void tick( uf::Object& );
static void render( uf::Object& );
static void destroy( uf::Object& );
};
}

View File

@ -48,12 +48,12 @@ std::vector<pod::GlyphBox> ext::Gui::generateGlyphs( const std::string& _string
uf::Object& gui = *this;
std::string string = _string;
uf::Serializer& metadata = gui.getComponent<uf::Serializer>();
std::string font = "./data/fonts/" + metadata["text settings"]["font"].asString();
std::string font = "./data/fonts/" + metadata["text settings"]["font"].as<std::string>();
if ( ::glyphs.cache[font].empty() ) {
ext::freetype::initialize( ::glyphs.glyph, font );
}
if ( string == "" ) {
string = metadata["text settings"]["string"].asString();
string = metadata["text settings"]["string"].as<std::string>();
}
pod::Transform<>& transform = gui.getComponent<pod::Transform<>>();
std::vector<pod::GlyphBox> gs;
@ -89,13 +89,13 @@ std::vector<pod::GlyphBox> ext::Gui::generateGlyphs( const std::string& _string
} colors;
} stat;
float scale = metadata["text settings"]["scale"].asFloat();
float scale = metadata["text settings"]["scale"].as<float>();
{
pod::Vector3f color = {
metadata["text settings"]["color"][0].asFloat(),
metadata["text settings"]["color"][1].asFloat(),
metadata["text settings"]["color"][2].asFloat(),
metadata["text settings"]["color"][0].as<float>(),
metadata["text settings"]["color"][1].as<float>(),
metadata["text settings"]["color"][2].as<float>(),
};
stat.colors.container.push_back(color);
}
@ -144,20 +144,20 @@ std::vector<pod::GlyphBox> ext::Gui::generateGlyphs( const std::string& _string
unsigned long c = *it; if ( c == '\n' ) continue; if ( c == '\t' ) continue; if ( c == 0x01 ) continue;
std::string key = ""; {
key += std::to_string(c) + ";";
key += metadata["text settings"]["padding"][0].asString() + ",";
key += metadata["text settings"]["padding"][1].asString() + ";";
key += metadata["text settings"]["spread"].asString() + ";";
key += metadata["text settings"]["size"].asString() + ";";
key += metadata["text settings"]["font"].asString() + ";";
key += metadata["text settings"]["sdf"].asString();
key += metadata["text settings"]["padding"][0].as<std::string>() + ",";
key += metadata["text settings"]["padding"][1].as<std::string>() + ";";
key += metadata["text settings"]["spread"].as<std::string>() + ";";
key += metadata["text settings"]["size"].as<std::string>() + ";";
key += metadata["text settings"]["font"].as<std::string>() + ";";
key += metadata["text settings"]["sdf"].as<std::string>();
}
uf::Glyph& glyph = ::glyphs.cache[font][key];
if ( !glyph.generated() ) {
glyph.setPadding( { metadata["text settings"]["padding"][0].asUInt(), metadata["text settings"]["padding"][1].asUInt() } );
glyph.setSpread( metadata["text settings"]["spread"].asUInt() );
if ( metadata["text settings"]["sdf"].asBool() ) glyph.useSdf(true);
glyph.generate( ::glyphs.glyph, c, metadata["text settings"]["size"].asInt() );
glyph.setPadding( { metadata["text settings"]["padding"][0].as<size_t>(), metadata["text settings"]["padding"][1].as<size_t>() } );
glyph.setSpread( metadata["text settings"]["spread"].as<size_t>() );
if ( metadata["text settings"]["sdf"].as<bool>() ) glyph.useSdf(true);
glyph.generate( ::glyphs.glyph, c, metadata["text settings"]["size"].as<int>() );
}
stat.biggest.x = std::max( (float) stat.biggest.x, (float) glyph.getSize().x);
@ -193,12 +193,12 @@ std::vector<pod::GlyphBox> ext::Gui::generateGlyphs( const std::string& _string
}
std::string key = ""; {
key += std::to_string(c) + ";";
key += metadata["text settings"]["padding"][0].asString() + ",";
key += metadata["text settings"]["padding"][1].asString() + ";";
key += metadata["text settings"]["spread"].asString() + ";";
key += metadata["text settings"]["size"].asString() + ";";
key += metadata["text settings"]["font"].asString() + ";";
key += metadata["text settings"]["sdf"].asString();
key += metadata["text settings"]["padding"][0].as<std::string>() + ",";
key += metadata["text settings"]["padding"][1].as<std::string>() + ";";
key += metadata["text settings"]["spread"].as<std::string>() + ";";
key += metadata["text settings"]["size"].as<std::string>() + ";";
key += metadata["text settings"]["font"].as<std::string>() + ";";
key += metadata["text settings"]["sdf"].as<std::string>();
}
uf::Glyph& glyph = ::glyphs.cache[font][key];
pod::GlyphBox g;
@ -212,13 +212,13 @@ std::vector<pod::GlyphBox> ext::Gui::generateGlyphs( const std::string& _string
stat.cursor.x += (glyph.getAdvance().x);
}
stat.origin.x = ( !metadata["text settings"]["world"].asBool() && transform.position.x != (int) transform.position.x ) ? transform.position.x * ext::gui::size.current.x : transform.position.x;
stat.origin.y = ( !metadata["text settings"]["world"].asBool() && transform.position.y != (int) transform.position.y ) ? transform.position.y * ext::gui::size.current.y : transform.position.y;
stat.origin.x = ( !metadata["text settings"]["world"].as<bool>() && transform.position.x != (int) transform.position.x ) ? transform.position.x * ext::gui::size.current.x : transform.position.x;
stat.origin.y = ( !metadata["text settings"]["world"].as<bool>() && transform.position.y != (int) transform.position.y ) ? transform.position.y * ext::gui::size.current.y : transform.position.y;
if ( metadata["text settings"]["origin"].isArray() ) {
stat.origin.x = metadata["text settings"]["origin"][0].asInt();
stat.origin.y = metadata["text settings"]["origin"][1].asInt();
if ( ext::json::isArray( metadata["text settings"]["origin"] ) ) {
stat.origin.x = metadata["text settings"]["origin"][0].as<int>();
stat.origin.y = metadata["text settings"]["origin"][1].as<int>();
}
else if ( metadata["text settings"]["origin"] == "top" ) stat.origin.y = ext::gui::size.current.y - stat.origin.y - stat.biggest.y;// else stat.origin.y = stat.origin.y;
if ( metadata["text settings"]["align"] == "right" ) stat.origin.x = ext::gui::size.current.x - stat.origin.x - stat.box.w;// else stat.origin.x = stat.origin.x;
@ -251,12 +251,12 @@ std::vector<pod::GlyphBox> ext::Gui::generateGlyphs( const std::string& _string
}
std::string key = ""; {
key += std::to_string(c) + ";";
key += metadata["text settings"]["padding"][0].asString() + ",";
key += metadata["text settings"]["padding"][1].asString() + ";";
key += metadata["text settings"]["spread"].asString() + ";";
key += metadata["text settings"]["size"].asString() + ";";
key += metadata["text settings"]["font"].asString() + ";";
key += metadata["text settings"]["sdf"].asString();
key += metadata["text settings"]["padding"][0].as<std::string>() + ",";
key += metadata["text settings"]["padding"][1].as<std::string>() + ";";
key += metadata["text settings"]["spread"].as<std::string>() + ";";
key += metadata["text settings"]["size"].as<std::string>() + ";";
key += metadata["text settings"]["font"].as<std::string>() + ";";
key += metadata["text settings"]["sdf"].as<std::string>();
}
uf::Glyph& glyph = ::glyphs.cache[font][key];
@ -276,9 +276,9 @@ std::vector<pod::GlyphBox> ext::Gui::generateGlyphs( const std::string& _string
} catch ( ... ) {
std::cout << "Invalid color index `" << stat.colors.index << "` for string: " << string << ": (" << stat.colors.container.size() << ")" << std::endl;
g.color = {
metadata["text settings"]["color"][0].asFloat(),
metadata["text settings"]["color"][1].asFloat(),
metadata["text settings"]["color"][2].asFloat(),
metadata["text settings"]["color"][0].as<float>(),
metadata["text settings"]["color"][1].as<float>(),
metadata["text settings"]["color"][2].as<float>(),
};
}
@ -307,15 +307,15 @@ void ext::Gui::load( uf::Image& image ) {
}
std::string suffix = ""; {
std::string _ = gui.getRootParent<uf::Scene>().getComponent<uf::Serializer>()["shaders"]["gui"]["suffix"].asString();
std::string _ = gui.getRootParent<uf::Scene>().getComponent<uf::Serializer>()["shaders"]["gui"]["suffix"].as<std::string>();
if ( _ != "" ) suffix = _ + ".";
}
if ( gui.getName() == "Gui: Text" ) {
pod::GlyphBox g;
g.box.x = metadata["text settings"]["box"][0].asFloat();
g.box.y = metadata["text settings"]["box"][1].asFloat();
g.box.w = metadata["text settings"]["box"][2].asFloat();
g.box.h = metadata["text settings"]["box"][3].asFloat();
g.box.x = metadata["text settings"]["box"][0].as<float>();
g.box.y = metadata["text settings"]["box"][1].as<float>();
g.box.w = metadata["text settings"]["box"][2].as<float>();
g.box.h = metadata["text settings"]["box"][3].as<float>();
mesh.vertices = {
{{ g.box.x, g.box.y + g.box.h }, { 0.0f, 0.0f }},
@ -337,8 +337,8 @@ void ext::Gui::load( uf::Image& image ) {
std::string vertex = "./data/shaders/gui.text.vert.spv";
std::string fragment = "./data/shaders/gui.text.frag.spv";
} filenames;
if ( metadata["shaders"]["vertex"].isString() ) filenames.vertex = metadata["shaders"]["vertex"].asString();
if ( metadata["shaders"]["fragment"].isString() ) filenames.fragment = metadata["shaders"]["fragment"].asString();
if ( metadata["shaders"]["vertex"].is<std::string>() ) filenames.vertex = metadata["shaders"]["vertex"].as<std::string>();
if ( metadata["shaders"]["fragment"].is<std::string>() ) filenames.fragment = metadata["shaders"]["fragment"].as<std::string>();
else if ( suffix != "" ) filenames.fragment = "./data/shaders/gui.text."+suffix+"frag.spv";
graphic.material.initializeShaders({
@ -361,8 +361,8 @@ void ext::Gui::load( uf::Image& image ) {
std::string vertex = "./data/shaders/gui.vert.spv";
std::string fragment = "./data/shaders/gui.frag.spv";
} filenames;
if ( metadata["shaders"]["vertex"].isString() ) filenames.vertex = metadata["shaders"]["vertex"].asString();
if ( metadata["shaders"]["fragment"].isString() ) filenames.fragment = metadata["shaders"]["fragment"].asString();
if ( metadata["shaders"]["vertex"].is<std::string>() ) filenames.vertex = metadata["shaders"]["vertex"].as<std::string>();
if ( metadata["shaders"]["fragment"].is<std::string>() ) filenames.fragment = metadata["shaders"]["fragment"].as<std::string>();
else if ( suffix != "" ) filenames.fragment = "./data/shaders/gui."+suffix+"frag.spv";
graphic.material.initializeShaders({
@ -381,39 +381,39 @@ void ext::Gui::load( uf::Image& image ) {
auto& texture = graphic.material.textures.front();
pod::Vector2f textureSize = {
metadata["original size"]["x"].asFloat(),
metadata["original size"]["y"].asFloat()
metadata["original size"]["x"].as<float>(),
metadata["original size"]["y"].as<float>()
};
if ( metadata["scaling"].asString() == "fixed" ) {
if ( metadata["scaling"].as<std::string>() == "fixed" ) {
transform.scale = pod::Vector3{ (float) textureSize.x / ext::gui::size.current.x, (float) textureSize.y / ext::gui::size.current.y, 1 };
} else if ( metadata["scaling"].asString() == "fixed-1080p" ) {
} else if ( metadata["scaling"].as<std::string>() == "fixed-1080p" ) {
transform.scale = pod::Vector3{ (float) textureSize.x / 1920, (float) textureSize.y / 1080, 1 };
}
}
}
EXT_OBJECT_REGISTER_BEGIN(Gui)
UF_OBJECT_REGISTER_BEHAVIOR(EntityBehavior)
UF_OBJECT_REGISTER_BEHAVIOR(ObjectBehavior)
EXT_OBJECT_REGISTER_BEHAVIOR(GuiBehavior)
EXT_OBJECT_REGISTER_END()
UF_OBJECT_REGISTER_BEGIN(ext::Gui)
UF_OBJECT_REGISTER_BEHAVIOR(uf::EntityBehavior)
UF_OBJECT_REGISTER_BEHAVIOR(uf::ObjectBehavior)
UF_OBJECT_REGISTER_BEHAVIOR(ext::GuiBehavior)
UF_OBJECT_REGISTER_END()
#define this (&self)
void ext::GuiBehavior::initialize( uf::Object& self ) {
auto& metadata = this->getComponent<uf::Serializer>();
this->addHook( "glyph:Load.%UID%", [&](const std::string& event)->std::string{
uf::Serializer json = event;
unsigned long c = json["glyph"].asUInt64();
std::string font = "./data/fonts/" + metadata["text settings"]["font"].asString();
unsigned long c = json["glyph"].as<size_t>();
std::string font = "./data/fonts/" + metadata["text settings"]["font"].as<std::string>();
std::string key = ""; {
key += std::to_string(c) + ";";
key += metadata["text settings"]["padding"][0].asString() + ",";
key += metadata["text settings"]["padding"][1].asString() + ";";
key += metadata["text settings"]["spread"].asString() + ";";
key += metadata["text settings"]["size"].asString() + ";";
key += metadata["text settings"]["font"].asString() + ";";
key += metadata["text settings"]["sdf"].asString();
key += metadata["text settings"]["padding"][0].as<std::string>() + ",";
key += metadata["text settings"]["padding"][1].as<std::string>() + ";";
key += metadata["text settings"]["spread"].as<std::string>() + ";";
key += metadata["text settings"]["size"].as<std::string>() + ";";
key += metadata["text settings"]["font"].as<std::string>() + ";";
key += metadata["text settings"]["sdf"].as<std::string>();
}
uf::Glyph& glyph = ::glyphs.cache[font][key];
@ -429,7 +429,7 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
});
this->addHook( "asset:Load.%UID%", [&](const std::string& event)->std::string{
uf::Serializer json = event;
std::string filename = json["filename"].asString();
std::string filename = json["filename"].as<std::string>();
if ( uf::io::extension(filename) != "png" ) return "false";
@ -449,50 +449,50 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
if ( !this->hasComponent<uf::GuiMesh>() ) return "false";
pod::Vector2ui size; {
size.x = json["window"]["size"]["x"].asUInt64();
size.y = json["window"]["size"]["y"].asUInt64();
size.x = json["window"]["size"]["x"].as<size_t>();
size.y = json["window"]["size"]["y"].as<size_t>();
}
pod::Transform<>& transform = this->getComponent<pod::Transform<>>();
// uf::Graphic& graphic = this->getComponent<uf::Graphic>();
// auto& texture = graphic.material.textures.front();
pod::Vector2f textureSize = {
metadata["original size"]["x"].asFloat(),
metadata["original size"]["y"].asFloat()
metadata["original size"]["x"].as<float>(),
metadata["original size"]["y"].as<float>()
};
if ( metadata["text settings"].isObject() ) {
} else if ( metadata["scaling"].asString() == "fixed" ) {
if ( ext::json::isObject( metadata["text settings"] ) ) {
} else if ( metadata["scaling"].as<std::string>() == "fixed" ) {
transform.scale = pod::Vector3{ (float) textureSize.x / size.x, (float) textureSize.y / size.y, 1 };
} else if ( metadata["scaling"].asString() == "fixed-1080p" ) {
} else if ( metadata["scaling"].as<std::string>() == "fixed-1080p" ) {
transform.scale = pod::Vector3{ (float) textureSize.x / 1920, (float) textureSize.y / 1080, 1 };
}
return "true";
} );
if ( metadata["system"]["clickable"].asBool() ) {
if ( metadata["system"]["clickable"].as<bool>() ) {
uf::Timer<long long> clickTimer(false);
// clickTimer.start( uf::Time<>(-1000000) );
if ( !clickTimer.running() ) clickTimer.start();
this->addHook( "gui:Clicked.%UID%", [&](const std::string& event)->std::string{
uf::Serializer json = event;
if ( metadata["events"]["click"].isObject() ) {
if ( ext::json::isObject( metadata["events"]["click"] ) ) {
uf::Serializer event = metadata["events"]["click"];
metadata["events"]["click"] = Json::arrayValue;
metadata["events"]["click"][0] = event;
} else if ( !metadata["events"]["click"].isArray() ) {
} else if ( !ext::json::isArray( metadata["events"]["click"] ) ) {
this->getParent().as<uf::Object>().callHook("gui:Clicked.%UID%", event);
return "false";
}
for ( int i = 0; i < metadata["events"]["click"].size(); ++i ) {
uf::Serializer event = metadata["events"]["click"][i];
uf::Serializer payload = event["payload"];
float delay = event["delay"].asFloat();
if ( event["delay"].isNumeric() ) {
this->queueHook(event["name"].asString(), payload, event["delay"].asFloat());
float delay = event["delay"].as<float>();
if ( event["delay"].is<double>() ) {
this->queueHook(event["name"].as<std::string>(), payload, event["delay"].as<float>());
} else {
this->callHook(event["name"].asString(), payload );
this->callHook(event["name"].as<std::string>(), payload );
}
}
return "true";
@ -502,15 +502,15 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
// if ( !this->hasComponent<uf::GuiMesh>() ) return "false";
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
if ( metadata["world"].asBool() ) return "true";
if ( metadata["world"].as<bool>() ) return "true";
if ( metadata["box"] == Json::nullValue ) return "true";
bool down = json["mouse"]["state"].asString() == "Down";
bool down = json["mouse"]["state"].as<std::string>() == "Down";
bool clicked = false;
if ( down ) {
pod::Vector2ui position; {
position.x = json["mouse"]["position"]["x"].asInt() > 0 ? json["mouse"]["position"]["x"].asUInt() : 0;
position.y = json["mouse"]["position"]["y"].asInt() > 0 ? json["mouse"]["position"]["y"].asUInt() : 0;
position.x = json["mouse"]["position"]["x"].as<int>() > 0 ? json["mouse"]["position"]["x"].as<size_t>() : 0;
position.y = json["mouse"]["position"]["y"].as<int>() > 0 ? json["mouse"]["position"]["y"].as<size_t>() : 0;
}
pod::Vector2f click; {
click.x = (float) position.x / (float) ext::gui::size.current.x;
@ -524,12 +524,12 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
if (json["invoker"] == "vr" ) {
x = json["mouse"]["position"]["x"].asFloat();
y = json["mouse"]["position"]["y"].asFloat();
x = json["mouse"]["position"]["x"].as<float>();
y = json["mouse"]["position"]["y"].as<float>();
}
pod::Vector2f min = { metadata["box"]["min"]["x"].asFloat(), metadata["box"]["min"]["y"].asFloat() };
pod::Vector2f max = { metadata["box"]["max"]["x"].asFloat(), metadata["box"]["max"]["y"].asFloat() };
pod::Vector2f min = { metadata["box"]["min"]["x"].as<float>(), metadata["box"]["min"]["y"].as<float>() };
pod::Vector2f max = { metadata["box"]["max"]["x"].as<float>(), metadata["box"]["max"]["y"].as<float>() };
clicked = ( min.x <= x && min.y <= y && max.x >= x && max.y >= y );
}
@ -541,28 +541,28 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
return "true";
} );
}
if ( metadata["system"]["hoverable"].asBool() ) {
if ( metadata["system"]["hoverable"].as<bool>() ) {
uf::Timer<long long> hoverTimer(false);
hoverTimer.start( uf::Time<>(-1000000) );
this->addHook( "gui:Hovered.%UID%", [&](const std::string& event)->std::string{
uf::Serializer json = event;
if ( metadata["events"]["hover"].isObject() ) {
if ( ext::json::isObject( metadata["events"]["hover"] ) ) {
uf::Serializer event = metadata["events"]["hover"];
metadata["events"]["hover"] = Json::arrayValue;
metadata["events"]["hover"][0] = event;
} else if ( !metadata["events"]["hover"].isArray() ) {
} else if ( !ext::json::isArray( metadata["events"]["hover"] ) ) {
this->getParent().as<uf::Object>().callHook("gui:Clicked.%UID%", event);
return "false";
}
for ( int i = 0; i < metadata["events"]["hover"].size(); ++i ) {
uf::Serializer event = metadata["events"]["hover"][i];
uf::Serializer payload = event["payload"];
float delay = event["delay"].asFloat();
if ( event["delay"].isNumeric() ) {
this->queueHook(event["name"].asString(), payload, event["delay"].asFloat());
float delay = event["delay"].as<float>();
if ( event["delay"].is<double>() ) {
this->queueHook(event["name"].as<std::string>(), payload, event["delay"].as<float>());
} else {
this->callHook(event["name"].asString(), payload );
this->callHook(event["name"].as<std::string>(), payload );
}
}
return "true";
@ -572,14 +572,14 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
if ( this->getUid() == 0 ) return "false";
if ( !this->hasComponent<uf::GuiMesh>() ) return "false";
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
if ( metadata["world"].asBool() ) return "true";
if ( metadata["world"].as<bool>() ) return "true";
if ( metadata["box"] == Json::nullValue ) return "true";
bool down = json["mouse"]["state"].asString() == "Down";
bool down = json["mouse"]["state"].as<std::string>() == "Down";
bool clicked = false;
pod::Vector2ui position; {
position.x = json["mouse"]["position"]["x"].asInt() > 0 ? json["mouse"]["position"]["x"].asUInt() : 0;
position.y = json["mouse"]["position"]["y"].asInt() > 0 ? json["mouse"]["position"]["y"].asUInt() : 0;
position.x = json["mouse"]["position"]["x"].as<int>() > 0 ? json["mouse"]["position"]["x"].as<size_t>() : 0;
position.y = json["mouse"]["position"]["y"].as<int>() > 0 ? json["mouse"]["position"]["y"].as<size_t>() : 0;
}
pod::Vector2f click; {
click.x = (float) position.x / (float) ext::gui::size.current.x;
@ -590,8 +590,8 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
float x = click.x;
float y = click.y;
pod::Vector2f min = { metadata["box"]["min"]["x"].asFloat(), metadata["box"]["min"]["y"].asFloat() };
pod::Vector2f max = { metadata["box"]["max"]["x"].asFloat(), metadata["box"]["max"]["y"].asFloat() };
pod::Vector2f min = { metadata["box"]["min"]["x"].as<float>(), metadata["box"]["min"]["y"].as<float>() };
pod::Vector2f max = { metadata["box"]["max"]["x"].as<float>(), metadata["box"]["max"]["y"].as<float>() };
clicked = ( min.x <= x && min.y <= y && max.x >= x && max.y >= y );
}
metadata["hovered"] = clicked;
@ -604,19 +604,19 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
return "true";
} );
}
if ( metadata["text settings"]["string"].isString() ) {
if ( ::defaultSettings["metadata"].isNull() ) {
if ( metadata["text settings"]["string"].is<std::string>() ) {
if ( ext::json::isNull( ::defaultSettings["metadata"] ) ) {
::defaultSettings.readFromFile("./data/entities/gui/text/string.json");
}
for ( auto it = ::defaultSettings["metadata"]["text settings"].begin(); it != ::defaultSettings["metadata"]["text settings"].end(); ++it ) {
std::string key = it.key().asString();
if ( metadata["text settings"][key].isNull() ) {
std::string key = it.key().as<std::string>();
if ( ext::json::isNull( metadata["text settings"][key] ) ) {
metadata["text settings"][key] = ::defaultSettings["metadata"]["text settings"][key];
}
}
if ( metadata["text settings"]["legacy"].asBool() ) {
if ( metadata["text settings"]["legacy"].as<bool>() ) {
float delay = 0.0f;
float scale = metadata["text settings"]["scale"].asFloat();
float scale = metadata["text settings"]["scale"].as<float>();
std::vector<pod::GlyphBox> glyphs = this->as<ext::Gui>().generateGlyphs();
for ( auto& glyph : glyphs ) {
uf::Object& glyphElement = this->loadChild("/gui/text/letter.json", false);
@ -650,9 +650,9 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
uf::Serializer payload;
payload["glyph"] = (uint64_t) glyph.code;
if ( metadata["text settings"]["scroll speed"].isNumeric() ) {
if ( metadata["text settings"]["scroll speed"].is<double>() ) {
glyphElement.queueHook("glyph:Load.%UID%", payload, delay);
delay += metadata["text settings"]["scroll speed"].asFloat();
delay += metadata["text settings"]["scroll speed"].as<float>();
} else {
glyphElement.callHook("glyph:Load.%UID%", payload);
}
@ -661,21 +661,21 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
}
{
float delay = 0.0f;
float scale = metadata["text settings"]["scale"].asFloat();
float scale = metadata["text settings"]["scale"].as<float>();
auto& transform = this->getComponent<pod::Transform<>>();
transform.scale.x = scale;
transform.scale.y = scale;
std::vector<pod::GlyphBox> glyphs = this->as<ext::Gui>().generateGlyphs();
std::string font = "./data/fonts/" + metadata["text settings"]["font"].asString();
std::string font = "./data/fonts/" + metadata["text settings"]["font"].as<std::string>();
std::string key = ""; {
key += metadata["text settings"]["padding"][0].asString() + ",";
key += metadata["text settings"]["padding"][1].asString() + ";";
key += metadata["text settings"]["spread"].asString() + ";";
key += metadata["text settings"]["size"].asString() + ";";
key += metadata["text settings"]["font"].asString() + ";";
key += metadata["text settings"]["sdf"].asString();
key += metadata["text settings"]["padding"][0].as<std::string>() + ",";
key += metadata["text settings"]["padding"][1].as<std::string>() + ";";
key += metadata["text settings"]["spread"].as<std::string>() + ";";
key += metadata["text settings"]["size"].as<std::string>() + ";";
key += metadata["text settings"]["font"].as<std::string>() + ";";
key += metadata["text settings"]["sdf"].as<std::string>();
}
auto& scene = uf::scene::getCurrentScene();
auto& atlas = this->getComponent<uf::Atlas>();
@ -722,15 +722,15 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
graphic.initializeGeometry( mesh );
std::string suffix = ""; {
std::string _ = scene.getComponent<uf::Serializer>()["shaders"]["gui"]["suffix"].asString();
std::string _ = scene.getComponent<uf::Serializer>()["shaders"]["gui"]["suffix"].as<std::string>();
if ( _ != "" ) suffix = _ + ".";
}
struct {
std::string vertex = "./data/shaders/gui.text.vert.spv";
std::string fragment = "./data/shaders/gui.text.frag.spv";
} filenames;
if ( metadata["shaders"]["vertex"].isString() ) filenames.vertex = metadata["shaders"]["vertex"].asString();
if ( metadata["shaders"]["fragment"].isString() ) filenames.fragment = metadata["shaders"]["fragment"].asString();
if ( metadata["shaders"]["vertex"].is<std::string>() ) filenames.vertex = metadata["shaders"]["vertex"].as<std::string>();
if ( metadata["shaders"]["fragment"].is<std::string>() ) filenames.fragment = metadata["shaders"]["fragment"].as<std::string>();
else if ( suffix != "" ) filenames.fragment = "./data/shaders/gui.text."+suffix+"frag.spv";
graphic.material.initializeShaders({
@ -749,28 +749,28 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
this->addHook( "gui:UpdateString.%UID%", [&](const std::string& event)->std::string{
uf::Serializer json = event;
for ( auto it = ::defaultSettings["metadata"]["text settings"].begin(); it != ::defaultSettings["metadata"]["text settings"].end(); ++it ) {
std::string key = it.key().asString();
if ( metadata["text settings"][key].isNull() ) {
std::string key = it.key().as<std::string>();
if ( ext::json::isNull( metadata["text settings"][key] ) ) {
metadata["text settings"][key] = ::defaultSettings["metadata"]["text settings"][key];
}
}
if ( json["string"].isString() ) {
if ( json["string"].is<std::string>() ) {
metadata["text settings"]["string"] = json["string"];
}
std::string string = metadata["text settings"]["string"].asString();
std::string string = metadata["text settings"]["string"].as<std::string>();
float delay = 0.0f;
float scale = metadata["text settings"]["scale"].asFloat();
float scale = metadata["text settings"]["scale"].as<float>();
std::vector<pod::GlyphBox> glyphs = this->as<ext::Gui>().generateGlyphs( string );
std::string font = "./data/fonts/" + metadata["text settings"]["font"].asString();
std::string font = "./data/fonts/" + metadata["text settings"]["font"].as<std::string>();
std::string key = ""; {
key += metadata["text settings"]["padding"][0].asString() + ",";
key += metadata["text settings"]["padding"][1].asString() + ";";
key += metadata["text settings"]["spread"].asString() + ";";
key += metadata["text settings"]["size"].asString() + ";";
key += metadata["text settings"]["font"].asString() + ";";
key += metadata["text settings"]["sdf"].asString();
key += metadata["text settings"]["padding"][0].as<std::string>() + ",";
key += metadata["text settings"]["padding"][1].as<std::string>() + ";";
key += metadata["text settings"]["spread"].as<std::string>() + ";";
key += metadata["text settings"]["size"].as<std::string>() + ";";
key += metadata["text settings"]["font"].as<std::string>() + ";";
key += metadata["text settings"]["sdf"].as<std::string>();
}
auto& transform = this->getComponent<pod::Transform<>>();
auto& scene = uf::scene::getCurrentScene();
@ -838,15 +838,15 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
graphic.initializeGeometry( mesh );
std::string suffix = ""; {
std::string _ = scene.getComponent<uf::Serializer>()["shaders"]["gui"]["suffix"].asString();
std::string _ = scene.getComponent<uf::Serializer>()["shaders"]["gui"]["suffix"].as<std::string>();
if ( _ != "" ) suffix = _ + ".";
}
struct {
std::string vertex = "./data/shaders/gui.text.vert.spv";
std::string fragment = "./data/shaders/gui.text.frag.spv";
} filenames;
if ( metadata["shaders"]["vertex"].isString() ) filenames.vertex = metadata["shaders"]["vertex"].asString();
if ( metadata["shaders"]["fragment"].isString() ) filenames.fragment = metadata["shaders"]["fragment"].asString();
if ( metadata["shaders"]["vertex"].is<std::string>() ) filenames.vertex = metadata["shaders"]["vertex"].as<std::string>();
if ( metadata["shaders"]["fragment"].is<std::string>() ) filenames.fragment = metadata["shaders"]["fragment"].as<std::string>();
else if ( suffix != "" ) filenames.fragment = "./data/shaders/gui.text."+suffix+"frag.spv";
graphic.material.initializeShaders({
@ -861,9 +861,9 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
}
void ext::GuiBehavior::tick( uf::Object& self ) {
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
if ( metadata["text settings"]["fade in speed"].isNumeric() && !metadata["system"]["faded in"].asBool() ) {
float speed = metadata["text settings"]["fade in speed"].asFloat();
float alpha = metadata["text settings"]["color"][3].asFloat();
if ( metadata["text settings"]["fade in speed"].is<double>() && !metadata["system"]["faded in"].as<bool>() ) {
float speed = metadata["text settings"]["fade in speed"].as<float>();
float alpha = metadata["text settings"]["color"][3].as<float>();
speed *= uf::physics::time::delta;
if ( alpha < 1 && alpha + speed > 1 ) {
alpha = 1;
@ -888,15 +888,15 @@ void ext::GuiBehavior::render( uf::Object& self ){
if ( !graphic.initialized ) return;
pod::Vector4 offset = {
metadata["uv"][0].asFloat(),
metadata["uv"][1].asFloat(),
metadata["uv"][2].asFloat(),
metadata["uv"][3].asFloat()
metadata["uv"][0].as<float>(),
metadata["uv"][1].as<float>(),
metadata["uv"][2].as<float>(),
metadata["uv"][3].as<float>()
};
int mode = 0;
if ( !metadata["shader"].isNull() ) mode = metadata["shader"].asInt();
if ( !ext::json::isNull( metadata["shader"] ) ) mode = metadata["shader"].as<int>();
if ( !metadata["text settings"]["legacy"].isNull() && ((metadata["text settings"]["legacy"].asBool() && this->getName() == "Gui: Text") || (!metadata["text settings"]["legacy"].asBool() && metadata["text settings"]["string"].isString())) ) {
if ( !ext::json::isNull( metadata["text settings"]["legacy"] ) && ((metadata["text settings"]["legacy"].as<bool>() && this->getName() == "Gui: Text") || (!metadata["text settings"]["legacy"].as<bool>() && metadata["text settings"]["string"].is<std::string>())) ) {
struct GlyphDescriptor {
struct {
alignas(16) pod::Matrix4f model[2];
@ -917,49 +917,49 @@ void ext::GuiBehavior::render( uf::Object& self ){
};
auto& uniforms = graphic.material.shaders.front().uniforms.front().get<GlyphDescriptor>();
if ( !metadata["text settings"]["color"].isArray() ) {
if ( !ext::json::isArray( metadata["text settings"]["color"] ) ) {
metadata["text settings"]["color"][0] = 1.0f;
metadata["text settings"]["color"][1] = 1.0f;
metadata["text settings"]["color"][2] = 1.0f;
metadata["text settings"]["color"][3] = 1.0f;
}
if ( !metadata["text settings"]["stroke"].isArray() ) {
if ( !ext::json::isArray( metadata["text settings"]["stroke"] ) ) {
metadata["text settings"]["stroke"][0] = 0.0f;
metadata["text settings"]["stroke"][1] = 0.0f;
metadata["text settings"]["stroke"][2] = 0.0f;
metadata["text settings"]["stroke"][3] = 1.0f;
}
pod::Vector4 color = {
metadata["text settings"]["color"][0].asFloat(),
metadata["text settings"]["color"][1].asFloat(),
metadata["text settings"]["color"][2].asFloat(),
metadata["text settings"]["color"][3].asFloat()
metadata["text settings"]["color"][0].as<float>(),
metadata["text settings"]["color"][1].as<float>(),
metadata["text settings"]["color"][2].as<float>(),
metadata["text settings"]["color"][3].as<float>()
};
if ( metadata["alpha"].isNumeric() ) {
color[3] *= metadata["alpha"].asFloat();
if ( metadata["alpha"].is<double>() ) {
color[3] *= metadata["alpha"].as<float>();
}
pod::Vector4 stroke = {
metadata["text settings"]["stroke"][0].asFloat(),
metadata["text settings"]["stroke"][1].asFloat(),
metadata["text settings"]["stroke"][2].asFloat(),
metadata["text settings"]["stroke"][3].asFloat()
metadata["text settings"]["stroke"][0].as<float>(),
metadata["text settings"]["stroke"][1].as<float>(),
metadata["text settings"]["stroke"][2].as<float>(),
metadata["text settings"]["stroke"][3].as<float>()
};
uniforms.gui.offset = offset;
uniforms.gui.color = color;
uniforms.gui.stroke = stroke;
uniforms.gui.mode = mode;
uniforms.gui.sdf = metadata["text settings"]["sdf"].asBool();
uniforms.gui.shadowbox = metadata["text settings"]["shadowbox"].asBool();
uniforms.gui.weight = metadata["text settings"]["weight"].asFloat(); // float
uniforms.gui.spread = metadata["text settings"]["spread"].asInt(); // int
uniforms.gui.scale = metadata["text settings"]["scale"].asFloat(); // float
if ( !metadata["text settings"]["depth"].isNull() )
uniforms.gui.depth = metadata["text settings"]["depth"].asFloat();
uniforms.gui.sdf = metadata["text settings"]["sdf"].as<bool>();
uniforms.gui.shadowbox = metadata["text settings"]["shadowbox"].as<bool>();
uniforms.gui.weight = metadata["text settings"]["weight"].as<float>(); // float
uniforms.gui.spread = metadata["text settings"]["spread"].as<int>(); // int
uniforms.gui.scale = metadata["text settings"]["scale"].as<float>(); // float
if ( !ext::json::isNull( metadata["text settings"]["depth"] ) )
uniforms.gui.depth = metadata["text settings"]["depth"].as<float>();
else uniforms.gui.depth = 0.0f;
for ( std::size_t i = 0; i < 2; ++i ) {
if ( metadata["text settings"]["world"].asBool() ) {
if ( metadata["text settings"]["world"].as<bool>() ) {
auto& scene = uf::scene::getCurrentScene();
auto& controller = scene.getController();
auto& camera = controller.getComponent<uf::Camera>();
@ -1034,20 +1034,20 @@ void ext::GuiBehavior::render( uf::Object& self ){
}
*/
} else {
if ( !metadata["color"].isArray() ) {
if ( !ext::json::isArray( metadata["color"] ) ) {
metadata["color"][0] = 1.0f;
metadata["color"][1] = 1.0f;
metadata["color"][2] = 1.0f;
metadata["color"][3] = 1.0f;
}
pod::Vector4 color = {
metadata["color"][0].asFloat(),
metadata["color"][1].asFloat(),
metadata["color"][2].asFloat(),
metadata["color"][3].asFloat()
metadata["color"][0].as<float>(),
metadata["color"][1].as<float>(),
metadata["color"][2].as<float>(),
metadata["color"][3].as<float>()
};
if ( metadata["alpha"].isNumeric() ) {
color[3] *= metadata["alpha"].asFloat();
if ( metadata["alpha"].is<double>() ) {
color[3] *= metadata["alpha"].as<float>();
}
struct UniformDescriptor {
struct {
@ -1065,13 +1065,13 @@ void ext::GuiBehavior::render( uf::Object& self ){
uniforms.gui.offset = offset;
uniforms.gui.color = color;
uniforms.gui.mode = mode;
if ( !metadata["depth"].isNull() )
uniforms.gui.depth = metadata["depth"].asFloat();
if ( !ext::json::isNull( metadata["depth"] ) )
uniforms.gui.depth = metadata["depth"].as<float>();
else
uniforms.gui.depth = 0;
for ( std::size_t i = 0; i < 2; ++i ) {
if ( metadata["world"].asBool() ) {
if ( metadata["world"].as<bool>() ) {
/*
pod::Transform<> flatten = uf::transform::flatten(camera.getTransform(), true);
pod::Matrix4 rotation = uf::quaternion::matrix( uf::vector::multiply( { 1, 1, 1, -1 }, flatten.orientation) );

View File

@ -42,8 +42,8 @@ ext::gui::Size ext::gui::size = {
};
EXT_BEHAVIOR_REGISTER_CPP(GuiManagerBehavior)
EXT_BEHAVIOR_REGISTER_AS_OBJECT(GuiManagerBehavior, GuiManager)
UF_BEHAVIOR_REGISTER_CPP(ext::GuiManagerBehavior)
UF_BEHAVIOR_REGISTER_AS_OBJECT(ext::GuiManagerBehavior, ext::GuiManager)
#define this (&self)
void ext::GuiManagerBehavior::initialize( uf::Object& self ) {
{
@ -65,8 +65,8 @@ void ext::GuiManagerBehavior::initialize( uf::Object& self ) {
uf::Serializer json = event;
pod::Vector2ui size; {
size.x = json["window"]["size"]["x"].asUInt64();
size.y = json["window"]["size"]["y"].asUInt64();
size.x = json["window"]["size"]["x"].as<size_t>();
size.y = json["window"]["size"]["y"].as<size_t>();
}
ext::gui::size.current = size;
// ext::gui::size.reference = size;
@ -76,11 +76,11 @@ void ext::GuiManagerBehavior::initialize( uf::Object& self ) {
this->addHook( "window:Mouse.Moved", [&](const std::string& event)->std::string{
uf::Serializer json = event;
bool down = json["mouse"]["state"].asString() == "Down";
bool down = json["mouse"]["state"].as<std::string>() == "Down";
bool clicked = false;
pod::Vector2ui position; {
position.x = json["mouse"]["position"]["x"].asInt() > 0 ? json["mouse"]["position"]["x"].asUInt() : 0;
position.y = json["mouse"]["position"]["y"].asInt() > 0 ? json["mouse"]["position"]["y"].asUInt() : 0;
position.x = json["mouse"]["position"]["x"].as<int>() > 0 ? json["mouse"]["position"]["x"].as<size_t>() : 0;
position.y = json["mouse"]["position"]["y"].as<int>() > 0 ? json["mouse"]["position"]["y"].as<size_t>() : 0;
}
pod::Vector2f click; {
click.x = (float) position.x / (float) ext::gui::size.current.x;
@ -96,7 +96,7 @@ void ext::GuiManagerBehavior::initialize( uf::Object& self ) {
auto& controller = scene.getController();
auto& metadata = controller.getComponent<uf::Serializer>();
if ( metadata["overlay"]["cursor"]["type"].asString() == "mouse" ) {
if ( metadata["overlay"]["cursor"]["type"].as<std::string>() == "mouse" ) {
metadata["overlay"]["cursor"]["position"][0] = click.x;
metadata["overlay"]["cursor"]["position"][1] = click.y;
}
@ -139,27 +139,27 @@ void ext::GuiManagerBehavior::render( uf::Object& self ){
for ( size_t i = 0; i < 2; ++i ) {
pod::Transform<> transform;
if ( metadata["overlay"]["position"].isArray() )
if ( ext::json::isArray( metadata["overlay"]["position"] ) )
transform.position = {
metadata["overlay"]["position"][0].asFloat(),
metadata["overlay"]["position"][1].asFloat(),
metadata["overlay"]["position"][2].asFloat(),
metadata["overlay"]["position"][0].as<float>(),
metadata["overlay"]["position"][1].as<float>(),
metadata["overlay"]["position"][2].as<float>(),
};
if ( metadata["overlay"]["scale"].isArray() )
if ( ext::json::isArray( metadata["overlay"]["scale"] ) )
transform.scale = {
metadata["overlay"]["scale"][0].asFloat(),
metadata["overlay"]["scale"][1].asFloat(),
metadata["overlay"]["scale"][2].asFloat(),
metadata["overlay"]["scale"][0].as<float>(),
metadata["overlay"]["scale"][1].as<float>(),
metadata["overlay"]["scale"][2].as<float>(),
};
if ( metadata["overlay"]["orientation"].isArray() )
if ( ext::json::isArray( metadata["overlay"]["orientation"] ) )
transform.orientation = {
metadata["overlay"]["orientation"][0].asFloat(),
metadata["overlay"]["orientation"][1].asFloat(),
metadata["overlay"]["orientation"][2].asFloat(),
metadata["overlay"]["orientation"][3].asFloat(),
metadata["overlay"]["orientation"][0].as<float>(),
metadata["overlay"]["orientation"][1].as<float>(),
metadata["overlay"]["orientation"][2].as<float>(),
metadata["overlay"]["orientation"][3].as<float>(),
};
if ( ext::openvr::enabled && (metadata["overlay"]["enabled"].asBool() || uf::renderer::getRenderMode("Stereoscopic Deferred", true).getType() == "Stereoscopic Deferred" )) {
if ( metadata["overlay"]["floating"].asBool() ) {
if ( ext::openvr::enabled && (metadata["overlay"]["enabled"].as<bool>() || uf::renderer::getRenderMode("Stereoscopic Deferred", true).getType() == "Stereoscopic Deferred" )) {
if ( metadata["overlay"]["floating"].as<bool>() ) {
pod::Matrix4f model = uf::transform::model( transform );
uniforms.matrices.models[i] = camera.getProjection(i) * ext::openvr::hmdEyePositionMatrix( i == 0 ? vr::Eye_Left : vr::Eye_Right ) * model;
} else {
@ -173,24 +173,24 @@ void ext::GuiManagerBehavior::render( uf::Object& self ){
pod::Matrix4t<> model = uf::matrix::translate( uf::matrix::identity(), { 0, 0, 1 } );
uniforms.matrices.models[i] = model;
}
// uniforms.alpha.x = metadata["overlay"]["alpha"].asFloat();
// uniforms.alpha.x = metadata["overlay"]["alpha"].as<float>();
// uniforms.alpha.y = 0;
uniforms.cursor.position.x = (metadata["overlay"]["cursor"]["position"][0].asFloat() + 1.0f) * 0.5f; //(::mouse.position.x + 1.0f) * 0.5f;
uniforms.cursor.position.y = (metadata["overlay"]["cursor"]["position"][1].asFloat() + 1.0f) * 0.5f; //(::mouse.position.y + 1.0f) * 0.5f;
uniforms.cursor.position.x = (metadata["overlay"]["cursor"]["position"][0].as<float>() + 1.0f) * 0.5f; //(::mouse.position.x + 1.0f) * 0.5f;
uniforms.cursor.position.y = (metadata["overlay"]["cursor"]["position"][1].as<float>() + 1.0f) * 0.5f; //(::mouse.position.y + 1.0f) * 0.5f;
pod::Vector3f cursorSize;
cursorSize.x = metadata["overlay"]["cursor"]["radius"].asFloat();
cursorSize.y = metadata["overlay"]["cursor"]["radius"].asFloat();
cursorSize.x = metadata["overlay"]["cursor"]["radius"].as<float>();
cursorSize.y = metadata["overlay"]["cursor"]["radius"].as<float>();
cursorSize = uf::matrix::multiply<float>( uf::matrix::inverse( uf::matrix::scale( uf::matrix::identity() , transform.scale) ), cursorSize );
uniforms.cursor.radius.x = cursorSize.x;
uniforms.cursor.radius.y = cursorSize.y;
uniforms.cursor.color.x = metadata["overlay"]["cursor"]["color"][0].asFloat();
uniforms.cursor.color.y = metadata["overlay"]["cursor"]["color"][1].asFloat();
uniforms.cursor.color.z = metadata["overlay"]["cursor"]["color"][2].asFloat();
uniforms.cursor.color.w = metadata["overlay"]["cursor"]["color"][3].asFloat();
uniforms.cursor.color.x = metadata["overlay"]["cursor"]["color"][0].as<float>();
uniforms.cursor.color.y = metadata["overlay"]["cursor"]["color"][1].as<float>();
uniforms.cursor.color.z = metadata["overlay"]["cursor"]["color"][2].as<float>();
uniforms.cursor.color.w = metadata["overlay"]["cursor"]["color"][3].as<float>();
}
shader.updateBuffer( (void*) &uniforms, sizeof(uniforms), 0 );
}

Some files were not shown because too many files have changed in this diff Show More