Reformat core module
This commit is contained in:
parent
924d60e99b
commit
100e1d7434
20 changed files with 702 additions and 662 deletions
|
@ -1,49 +1,49 @@
|
|||
set(SRC
|
||||
include/engine.hpp
|
||||
include/app.hpp
|
||||
include/input.hpp
|
||||
include/cutscene.hpp
|
||||
include/physics.hpp
|
||||
include/scene.hpp
|
||||
include/imgui_backend.hpp
|
||||
include/object.hpp
|
||||
include/debug.hpp
|
||||
include/components.hpp
|
||||
include/imgui_utility.hpp
|
||||
include/console.hpp
|
||||
include/engine.hpp
|
||||
include/app.hpp
|
||||
include/input.hpp
|
||||
include/cutscene.hpp
|
||||
include/physics.hpp
|
||||
include/scene.hpp
|
||||
include/imgui_backend.hpp
|
||||
include/object.hpp
|
||||
include/debug.hpp
|
||||
include/components.hpp
|
||||
include/imgui_utility.hpp
|
||||
include/console.hpp
|
||||
|
||||
src/file.cpp
|
||||
src/engine.cpp
|
||||
src/input.cpp
|
||||
src/physics.cpp
|
||||
src/imgui_backend.cpp
|
||||
src/scene.cpp
|
||||
src/debug.cpp
|
||||
src/console.cpp)
|
||||
src/file.cpp
|
||||
src/engine.cpp
|
||||
src/input.cpp
|
||||
src/physics.cpp
|
||||
src/imgui_backend.cpp
|
||||
src/scene.cpp
|
||||
src/debug.cpp
|
||||
src/console.cpp)
|
||||
|
||||
if(NOT ENABLE_IOS AND NOT ENABLE_TVOS)
|
||||
if (NOT ENABLE_IOS AND NOT ENABLE_TVOS)
|
||||
set(EXTRA_LIBRARIES Audio)
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
add_library(Core STATIC ${SRC})
|
||||
target_include_directories(Core PUBLIC
|
||||
include)
|
||||
include)
|
||||
target_include_directories(Core SYSTEM PUBLIC
|
||||
${CMAKE_BINARY_DIR}/_deps/bullet-src/src)
|
||||
${CMAKE_BINARY_DIR}/_deps/bullet-src/src)
|
||||
target_link_libraries(Core PUBLIC
|
||||
Asset
|
||||
Math
|
||||
Utility
|
||||
nlohmann_json
|
||||
Log
|
||||
PRIVATE
|
||||
GFX
|
||||
Renderer
|
||||
magic_enum
|
||||
imgui
|
||||
Platform
|
||||
${EXTRA_LIBRARIES}
|
||||
BulletDynamics
|
||||
BulletCollision
|
||||
LinearMath)
|
||||
Asset
|
||||
Math
|
||||
Utility
|
||||
nlohmann_json
|
||||
Log
|
||||
PRIVATE
|
||||
GFX
|
||||
Renderer
|
||||
magic_enum
|
||||
imgui
|
||||
Platform
|
||||
${EXTRA_LIBRARIES}
|
||||
BulletDynamics
|
||||
BulletCollision
|
||||
LinearMath)
|
||||
set_engine_properties(Core)
|
|
@ -29,10 +29,15 @@ namespace prism {
|
|||
|
||||
virtual void render([[maybe_unused]] GFXCommandBuffer* command_buffer) {}
|
||||
|
||||
virtual bool wants_no_scene_rendering() { return false; }
|
||||
virtual bool is_multimodal() { return false; }
|
||||
virtual bool wants_no_scene_rendering() {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool is_multimodal() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
} // namespace prism
|
||||
|
||||
/// This is an app's equivalent of main(). You can check command line arguments through Engine::command_line_arguments.
|
||||
void app_main(prism::engine* engine);
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
#include <vector>
|
||||
|
||||
#include "assetptr.hpp"
|
||||
#include "matrix.hpp"
|
||||
#include "object.hpp"
|
||||
#include "quaternion.hpp"
|
||||
#include "matrix.hpp"
|
||||
|
||||
class btCollisionShape;
|
||||
class btRigidBody;
|
||||
|
@ -63,23 +63,19 @@ struct Transform {
|
|||
Matrix4x4 model;
|
||||
|
||||
[[nodiscard]] prism::float3 get_world_position() const {
|
||||
return {
|
||||
model[3][0],
|
||||
model[3][1],
|
||||
model[3][2]
|
||||
};
|
||||
return {model[3][0], model[3][1], model[3][2]};
|
||||
}
|
||||
};
|
||||
|
||||
struct Renderable {
|
||||
AssetPtr<Mesh> mesh;
|
||||
std::vector<AssetPtr<Material>> materials;
|
||||
|
||||
|
||||
std::vector<Matrix4x4> temp_bone_data;
|
||||
};
|
||||
|
||||
struct Light {
|
||||
enum class Type : int{
|
||||
enum class Type : int {
|
||||
Point = 0,
|
||||
Spot = 1,
|
||||
Sun = 2
|
||||
|
@ -94,7 +90,7 @@ struct Light {
|
|||
bool enable_shadows = true;
|
||||
bool use_dynamic_shadows = false;
|
||||
};
|
||||
|
||||
|
||||
struct Camera {
|
||||
float fov = 75.0f;
|
||||
float near = 0.1f;
|
||||
|
@ -105,6 +101,6 @@ struct Camera {
|
|||
struct EnvironmentProbe {
|
||||
bool is_sized = true;
|
||||
prism::float3 size = prism::float3(10);
|
||||
|
||||
|
||||
float intensity = 1.0;
|
||||
};
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <variant>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "path.hpp"
|
||||
|
||||
|
@ -59,15 +59,14 @@ namespace prism::console {
|
|||
|
||||
void load_cfg(const prism::path& path);
|
||||
|
||||
void
|
||||
register_command(std::string_view name, argument_format expected_format, function_ptr function);
|
||||
void register_command(std::string_view name, argument_format expected_format, function_ptr function);
|
||||
|
||||
void invoke_command(std::string_view name, arguments arguments);
|
||||
|
||||
void parse_and_invoke_command(std::string_view command);
|
||||
|
||||
void register_variable(std::string_view name, bool &variable);
|
||||
void register_variable(std::string_view name, bool& variable);
|
||||
void register_variable(std::string_view name, float& variable);
|
||||
void register_variable(std::string_view name, int& variable);
|
||||
void register_variable(std::string_view name, double& variable);
|
||||
}
|
||||
} // namespace prism::console
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include "vector.hpp"
|
||||
#include "quaternion.hpp"
|
||||
#include "math.hpp"
|
||||
#include "object.hpp"
|
||||
#include "quaternion.hpp"
|
||||
#include "vector.hpp"
|
||||
|
||||
struct PositionKeyFrame {
|
||||
float time;
|
||||
|
@ -33,7 +33,7 @@ struct AnimationChannel {
|
|||
|
||||
prism::Object target = prism::NullObject;
|
||||
Bone* bone = nullptr;
|
||||
|
||||
|
||||
std::vector<PositionKeyFrame> positions;
|
||||
std::vector<RotationKeyFrame> rotations;
|
||||
std::vector<ScaleKeyFrame> scales;
|
||||
|
@ -46,7 +46,7 @@ inline bool operator==(const AnimationChannel& lhs, const AnimationChannel& rhs)
|
|||
struct Animation {
|
||||
double ticks_per_second = 0.0;
|
||||
double duration = 0.0;
|
||||
|
||||
|
||||
std::vector<AnimationChannel> channels;
|
||||
};
|
||||
|
||||
|
@ -54,9 +54,9 @@ class Scene;
|
|||
|
||||
struct Shot {
|
||||
int begin, length;
|
||||
|
||||
|
||||
std::vector<AnimationChannel> channels;
|
||||
|
||||
|
||||
Scene* scene = nullptr;
|
||||
};
|
||||
|
||||
|
@ -67,15 +67,14 @@ inline bool operator==(const Shot& lhs, const Shot& rhs) {
|
|||
class Cutscene {
|
||||
public:
|
||||
std::vector<Shot> shots;
|
||||
|
||||
|
||||
int get_real_end() {
|
||||
int end = -1;
|
||||
for(auto& shot : shots) {
|
||||
if((shot.begin + shot.length) >= end)
|
||||
for (auto& shot : shots) {
|
||||
if ((shot.begin + shot.length) >= end)
|
||||
end = shot.begin + shot.length;
|
||||
|
||||
}
|
||||
|
||||
|
||||
return end;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
#include "object.hpp"
|
||||
#include "cutscene.hpp"
|
||||
#include "common.hpp"
|
||||
#include "asset_types.hpp"
|
||||
#include "platform.hpp"
|
||||
#include "common.hpp"
|
||||
#include "cutscene.hpp"
|
||||
#include "object.hpp"
|
||||
#include "path.hpp"
|
||||
#include "platform.hpp"
|
||||
|
||||
class GFX;
|
||||
class Scene;
|
||||
|
@ -87,10 +87,12 @@ namespace prism {
|
|||
*/
|
||||
[[nodiscard]] bool is_paused() const;
|
||||
|
||||
/// Request to begin quitting immediately. This is not forced, and can be canceled by the user, platform, or app.
|
||||
/// Request to begin quitting immediately. This is not forced, and can be canceled by the user, platform, or
|
||||
/// app.
|
||||
void quit();
|
||||
|
||||
/// Call right before the platform is about to quit the application, and requests the app or other systems to save work.
|
||||
/// Call right before the platform is about to quit the application, and requests the app or other systems to
|
||||
/// save work.
|
||||
void prepare_quit();
|
||||
|
||||
/// Query whether or not the engine is in the process of quitting.
|
||||
|
@ -198,26 +200,29 @@ namespace prism {
|
|||
/** Called when the window has moved.
|
||||
*
|
||||
*/
|
||||
void move(platform::window_ptr identifier);
|
||||
void move(platform::window_ptr identifier);
|
||||
|
||||
/** Called when a key has been pressed.
|
||||
@param keyCode A platform-specific key code.
|
||||
@note Use platform::get_keycode to get a InputButton equivalent if needed.
|
||||
@note This function is only intended for debug purposes and all production code should be using the Input system instead.
|
||||
@note This function is only intended for debug purposes and all production code should be using the Input
|
||||
system instead.
|
||||
*/
|
||||
void process_key_down(unsigned int keyCode);
|
||||
|
||||
/** Called when a key has been released.
|
||||
@param keyCode A platform-specific key code.
|
||||
@note Use platform::get_keycode to get a InputButton equivalent if needed.
|
||||
@note This function is only intended for debug purposes and all production code should be using the Input system instead.
|
||||
@note This function is only intended for debug purposes and all production code should be using the Input
|
||||
system instead.
|
||||
*/
|
||||
void process_key_up(unsigned int keyCode);
|
||||
|
||||
/** Called when a mouse button has been clicked..
|
||||
@param button The mouse button.
|
||||
@param offset The mouse position relative to the window where the click occured.
|
||||
@note This function is only intended for debug purposes and all production code should be using the Input system instead.
|
||||
@note This function is only intended for debug purposes and all production code should be using the Input
|
||||
system instead.
|
||||
*/
|
||||
void process_mouse_down(int button, prism::Offset offset);
|
||||
|
||||
|
@ -229,7 +234,8 @@ namespace prism {
|
|||
|
||||
/** Adds a timer to the list of timers.
|
||||
@param timer The timer to add.
|
||||
@note The timer instance is passed by reference. Use this to keep track of your timers without having to query it's state back.
|
||||
@note The timer instance is passed by reference. Use this to keep track of your timers without having to query
|
||||
it's state back.
|
||||
*/
|
||||
void add_timer(Timer& timer);
|
||||
|
||||
|
@ -250,7 +256,8 @@ namespace prism {
|
|||
void set_current_scene(Scene* scene);
|
||||
|
||||
/** Get the current scene's path.
|
||||
@return If a scene is loaded, the path to the scene. Can be an empty string if there is no scene loaded, or if it's an empty scene.
|
||||
@return If a scene is loaded, the path to the scene. Can be an empty string if there is no scene loaded, or if
|
||||
it's an empty scene.
|
||||
*/
|
||||
[[nodiscard]] std::string_view get_scene_path() const;
|
||||
|
||||
|
@ -281,7 +288,8 @@ namespace prism {
|
|||
|
||||
/** Sets the animation speed of an object.
|
||||
@param target The object you want to change the animation speed of.
|
||||
@param modifier The speed to play the object's animations at. A modifier of 2.0 would be 2x the speed, and 0.5 would be 1/2x the speed.
|
||||
@param modifier The speed to play the object's animations at. A modifier of 2.0 would be 2x the speed, and 0.5
|
||||
would be 1/2x the speed.
|
||||
*/
|
||||
void set_animation_speed_modifier(Object target, float modifier);
|
||||
|
||||
|
@ -290,7 +298,8 @@ namespace prism {
|
|||
*/
|
||||
void stop_animation(Object target);
|
||||
|
||||
/// If there is a render context available. If this is false, avoid doing any GFX or Renderer work as it could crash or cause undefined behavior.
|
||||
/// If there is a render context available. If this is false, avoid doing any GFX or Renderer work as it could
|
||||
/// crash or cause undefined behavior.
|
||||
bool render_ready = false;
|
||||
|
||||
/// If physics should upate. This is a control indepentent of the pause state.
|
||||
|
@ -328,8 +337,8 @@ namespace prism {
|
|||
std::vector<Window*> windows;
|
||||
|
||||
Window* get_window(const platform::window_ptr identifier) {
|
||||
for(auto& window : windows) {
|
||||
if(window->identifier == identifier)
|
||||
for (auto& window : windows) {
|
||||
if (window->identifier == identifier)
|
||||
return window;
|
||||
}
|
||||
|
||||
|
@ -366,6 +375,6 @@ namespace prism {
|
|||
inline bool operator==(const AnimationTarget& a1, const AnimationTarget& a2) {
|
||||
return a1.current_time == a2.current_time;
|
||||
}
|
||||
}
|
||||
} // namespace prism
|
||||
|
||||
inline prism::engine* engine = nullptr;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
#include <filesystem>
|
||||
#include <functional>
|
||||
#include <string_view>
|
||||
|
||||
#include "platform.hpp"
|
||||
|
||||
|
@ -27,13 +27,15 @@ namespace prism {
|
|||
|
||||
/**Opens a file dialog to select a file. This will not block.
|
||||
@param existing Whether or not to limit to existing files.
|
||||
@param returnFunction The callback function when a file is selected or the dialog is cancelled. An empy string is returned when cancelled.
|
||||
@param returnFunction The callback function when a file is selected or the dialog is cancelled. An empy string
|
||||
is returned when cancelled.
|
||||
@param openDirectory Whether or not to allow selecting directories as well.
|
||||
*/
|
||||
void open_dialog(bool existing, std::function<void(std::string)> returnFunction, bool openDirectory = false);
|
||||
|
||||
/**Opens a file dialog to select a save location for a file. This will not block.
|
||||
@param returnFunction The callback function when a file is selected or the dialog is cancelled. An empy string is returned when cancelled.
|
||||
@param returnFunction The callback function when a file is selected or the dialog is cancelled. An empy string
|
||||
is returned when cancelled.
|
||||
*/
|
||||
void save_dialog(std::function<void(std::string)> returnFunction);
|
||||
|
||||
|
@ -53,4 +55,4 @@ namespace prism {
|
|||
dialog_data open_dialog_data;
|
||||
dialog_data save_dialog_data;
|
||||
};
|
||||
}
|
||||
} // namespace prism
|
||||
|
|
|
@ -2,40 +2,38 @@
|
|||
|
||||
#include <imgui.h>
|
||||
|
||||
#include "utility.hpp"
|
||||
#include "math.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
namespace ImGui {
|
||||
template<typename T>
|
||||
inline bool ComboEnum(const char* label, T* t) {
|
||||
template<typename T> inline bool ComboEnum(const char* label, T* t) {
|
||||
bool result = false;
|
||||
|
||||
|
||||
const auto preview_value = utility::enum_to_string(*t);
|
||||
|
||||
|
||||
if (ImGui::BeginCombo(label, preview_value.c_str())) {
|
||||
for(auto& name : magic_enum::enum_values<T>()) {
|
||||
for (auto& name : magic_enum::enum_values<T>()) {
|
||||
const auto n = utility::enum_to_string(name);
|
||||
|
||||
|
||||
if (ImGui::Selectable(n.c_str(), *t == name)) {
|
||||
*t = name;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T, typename TMax>
|
||||
void ProgressBar(const char* label, const T value, const TMax max) {
|
||||
template<typename T, typename TMax> void ProgressBar(const char* label, const T value, const TMax max) {
|
||||
const float progress_saturated = value / static_cast<float>(max);
|
||||
|
||||
|
||||
char buf[32] = {};
|
||||
sprintf(buf, "%d/%d", static_cast<int>(value), static_cast<int>(max));
|
||||
ImGui::ProgressBar(progress_saturated, ImVec2(0.0f, 0.0f), buf);
|
||||
|
||||
|
||||
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
||||
ImGui::Text("%s", label);
|
||||
}
|
||||
|
@ -44,21 +42,21 @@ namespace ImGui {
|
|||
bool result = false;
|
||||
|
||||
prism::float3 euler = quat_to_euler(*quat);
|
||||
|
||||
|
||||
euler.x = degrees(euler.x);
|
||||
euler.y = degrees(euler.y);
|
||||
euler.z = degrees(euler.z);
|
||||
|
||||
if(ImGui::DragFloat3(label, euler.ptr(), 1.0f, 0.0f, 0.0f, "%.3f°")) {
|
||||
|
||||
if (ImGui::DragFloat3(label, euler.ptr(), 1.0f, 0.0f, 0.0f, "%.3f°")) {
|
||||
euler.x = radians(euler.x);
|
||||
euler.y = radians(euler.y);
|
||||
euler.z = radians(euler.z);
|
||||
|
||||
|
||||
*quat = euler_to_quat(euler);
|
||||
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
} // namespace ImGui
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "platform.hpp"
|
||||
|
||||
|
@ -42,20 +42,20 @@ namespace prism {
|
|||
/** Add a new binding.
|
||||
@param name The binding name.
|
||||
*/
|
||||
void add_binding(const std::string &name);
|
||||
void add_binding(const std::string& name);
|
||||
|
||||
/** Ties a button-type input to the binding.
|
||||
@param name The binding name.
|
||||
@param button The button to associate with.
|
||||
@param value The resulting input value when the button is pressed. Default is 1.0.
|
||||
*/
|
||||
void add_binding_button(const std::string &name, InputButton button, float value = 1.0f);
|
||||
void add_binding_button(const std::string& name, InputButton button, float value = 1.0f);
|
||||
|
||||
/** Ties an axis-type input to the button.
|
||||
@param name The binding name.
|
||||
@param button The axis to associate with.
|
||||
*/
|
||||
void add_binding_axis(const std::string &name, axis axis);
|
||||
void add_binding_axis(const std::string& name, axis axis);
|
||||
|
||||
/** Gets the input value of a binding.
|
||||
@param name The binding name.
|
||||
|
@ -63,20 +63,23 @@ namespace prism {
|
|||
@note If this binding is tied to a button-type input, assume that 0.0 means not pressed.
|
||||
@note If this binding is tied to an axis-type input, assume that 0.0 means the stick is centered.
|
||||
*/
|
||||
float get_value(const std::string &name);
|
||||
float get_value(const std::string& name);
|
||||
|
||||
/** Gets whether or not the binding is pressed.
|
||||
@param name The binding name.
|
||||
@param repeating If true, return a correct value regardless if it was identical for multiple frames. If false, any continued input past the first frame of being pressed is ignored and the input is considered released.
|
||||
@return If the binding is found, return true if the binding value is 1.0. If no binding is found or if the binding has continued pressing and repeating is turned off, returns false.
|
||||
@param repeating If true, return a correct value regardless if it was identical for multiple frames. If false,
|
||||
any continued input past the first frame of being pressed is ignored and the input is considered released.
|
||||
@return If the binding is found, return true if the binding value is 1.0. If no binding is found or if the
|
||||
binding has continued pressing and repeating is turned off, returns false.
|
||||
*/
|
||||
bool is_pressed(const std::string &name, bool repeating = false);
|
||||
bool is_pressed(const std::string& name, bool repeating = false);
|
||||
|
||||
/** Queries if the binding is repeating it's input.
|
||||
@param name The binding name.
|
||||
@return If the binding is found, returns true if the binding's values have been identical for multiple frames. Returns false if the binding is not found.
|
||||
@return If the binding is found, returns true if the binding's values have been identical for multiple frames.
|
||||
Returns false if the binding is not found.
|
||||
*/
|
||||
bool is_repeating(const std::string &name);
|
||||
bool is_repeating(const std::string& name);
|
||||
|
||||
/// Returns all of the bindings registered with this Input system.
|
||||
[[nodiscard]] std::vector<input_binding> get_bindings() const;
|
||||
|
@ -93,4 +96,4 @@ namespace prism {
|
|||
|
||||
bool _in_text_input = false;
|
||||
};
|
||||
}
|
||||
} // namespace prism
|
|
@ -5,4 +5,4 @@
|
|||
namespace prism {
|
||||
using Object = uint64_t;
|
||||
constexpr Object NullObject = 0;
|
||||
}
|
||||
} // namespace prism
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
#include "vector.hpp"
|
||||
#include "object.hpp"
|
||||
#include "vector.hpp"
|
||||
|
||||
class btBroadphaseInterface;
|
||||
class btDefaultCollisionConfiguration;
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include <unordered_map>
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <functional>
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "object.hpp"
|
||||
#include "components.hpp"
|
||||
#include "object.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
template<class Component>
|
||||
using Pool = std::unordered_map<prism::Object, Component>;
|
||||
template<class Component> using Pool = std::unordered_map<prism::Object, Component>;
|
||||
|
||||
template<class... Components>
|
||||
class ObjectComponents : Pool<Components>... {
|
||||
template<class... Components> class ObjectComponents : Pool<Components>... {
|
||||
public:
|
||||
/** Adds a new object.
|
||||
@param parent The object to parent the new object to. Default is null.
|
||||
|
@ -28,7 +26,7 @@ public:
|
|||
|
||||
return new_index;
|
||||
}
|
||||
|
||||
|
||||
/// Adds a new object but with a manually specified id.
|
||||
prism::Object add_object_by_id(const prism::Object id) {
|
||||
add<Data>(id);
|
||||
|
@ -46,8 +44,8 @@ public:
|
|||
|
||||
/// Find an object by name.
|
||||
[[nodiscard]] prism::Object find_object(const std::string_view name) const {
|
||||
for(auto& obj : _objects) {
|
||||
if(get<Data>(obj).name == name)
|
||||
for (auto& obj : _objects) {
|
||||
if (get<Data>(obj).name == name)
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -82,11 +80,11 @@ public:
|
|||
[[nodiscard]] std::vector<prism::Object> children_of(const prism::Object obj, const bool recursive = false) const {
|
||||
std::vector<prism::Object> vec;
|
||||
|
||||
if(recursive) {
|
||||
if (recursive) {
|
||||
recurse_children(vec, obj);
|
||||
} else {
|
||||
for(auto& o : _objects) {
|
||||
if(get(o).parent == obj)
|
||||
for (auto& o : _objects) {
|
||||
if (get(o).parent == obj)
|
||||
vec.push_back(o);
|
||||
}
|
||||
}
|
||||
|
@ -95,33 +93,28 @@ public:
|
|||
}
|
||||
|
||||
/// Adds a component.
|
||||
template<class Component>
|
||||
Component& add(const prism::Object object) {
|
||||
template<class Component> Component& add(const prism::Object object) {
|
||||
return Pool<Component>::emplace(object, Component()).first->second;
|
||||
}
|
||||
|
||||
/// Returns a component.
|
||||
template<class Component = Data>
|
||||
Component& get(const prism::Object object) {
|
||||
template<class Component = Data> Component& get(const prism::Object object) {
|
||||
return Pool<Component>::at(object);
|
||||
}
|
||||
|
||||
|
||||
/// Returns a component.
|
||||
template<class Component = Data>
|
||||
Component get(const prism::Object object) const {
|
||||
template<class Component = Data> Component get(const prism::Object object) const {
|
||||
return Pool<Component>::at(object);
|
||||
}
|
||||
|
||||
/// Checks whether or not an object has a certain component.
|
||||
template<class Component>
|
||||
[[nodiscard]] bool has(const prism::Object object) const {
|
||||
template<class Component> [[nodiscard]] bool has(const prism::Object object) const {
|
||||
return Pool<Component>::count(object);
|
||||
}
|
||||
|
||||
/// Removes a component from an object. Is a no-op if the component wasn't attached.
|
||||
template<class Component>
|
||||
bool remove(const prism::Object object) {
|
||||
if(has<Component>(object)) {
|
||||
template<class Component> bool remove(const prism::Object object) {
|
||||
if (has<Component>(object)) {
|
||||
Pool<Component>::erase(object);
|
||||
return true;
|
||||
} else {
|
||||
|
@ -130,11 +123,10 @@ public:
|
|||
}
|
||||
|
||||
/// Returns all instances of a component.
|
||||
template<class Component>
|
||||
std::vector<std::tuple<prism::Object, Component&>> get_all() {
|
||||
template<class Component> std::vector<std::tuple<prism::Object, Component&>> get_all() {
|
||||
std::vector<std::tuple<prism::Object, Component&>> comps;
|
||||
|
||||
for(auto it = Pool<Component>::begin(); it != Pool<Component>::end(); it++)
|
||||
for (auto it = Pool<Component>::begin(); it != Pool<Component>::end(); it++)
|
||||
comps.emplace_back(it->first, it->second);
|
||||
|
||||
return comps;
|
||||
|
@ -154,7 +146,7 @@ private:
|
|||
}
|
||||
|
||||
void recurse_remove(prism::Object obj) {
|
||||
for(auto& o : children_of(obj))
|
||||
for (auto& o : children_of(obj))
|
||||
recurse_remove(o);
|
||||
|
||||
utility::erase(_objects, obj);
|
||||
|
@ -165,22 +157,21 @@ private:
|
|||
}
|
||||
|
||||
void check_prefab_parent(prism::Object obj, bool& p) const {
|
||||
if(!get(obj).prefab_path.empty())
|
||||
if (!get(obj).prefab_path.empty())
|
||||
p = true;
|
||||
|
||||
if(get(obj).parent != prism::NullObject)
|
||||
if (get(obj).parent != prism::NullObject)
|
||||
check_prefab_parent(get(obj).parent, p);
|
||||
}
|
||||
|
||||
template<class Component>
|
||||
void add_duplicate_component(const prism::Object from, const prism::Object to) {
|
||||
if(Pool<Component>::count(from))
|
||||
template<class Component> void add_duplicate_component(const prism::Object from, const prism::Object to) {
|
||||
if (Pool<Component>::count(from))
|
||||
Pool<Component>::emplace(to, Pool<Component>::at(from));
|
||||
}
|
||||
|
||||
void recurse_children(std::vector<prism::Object>& vec, prism::Object obj) const {
|
||||
for(const auto o : _objects) {
|
||||
if(get(o).parent == obj) {
|
||||
for (const auto o : _objects) {
|
||||
if (get(o).parent == obj) {
|
||||
vec.push_back(o);
|
||||
|
||||
recurse_children(vec, o);
|
||||
|
@ -201,45 +192,47 @@ class GFXFramebuffer;
|
|||
class GFXTexture;
|
||||
|
||||
/// Represents a scene consisting of Objects with varying Components.
|
||||
class Scene : public ObjectComponents<Data, Transform, Renderable, Light, Camera, Collision, Rigidbody, EnvironmentProbe> {
|
||||
class Scene
|
||||
: public ObjectComponents<Data, Transform, Renderable, Light, Camera, Collision, Rigidbody, EnvironmentProbe> {
|
||||
public:
|
||||
/// If loaded from disk, the path to the scene file this originated from.
|
||||
std::string path;
|
||||
|
||||
/// Invalidates the current shadow data for all shadowed lights. This may cause stuttering while the data is regenerated.
|
||||
|
||||
/// Invalidates the current shadow data for all shadowed lights. This may cause stuttering while the data is
|
||||
/// regenerated.
|
||||
void reset_shadows() {
|
||||
sun_light_dirty = true;
|
||||
|
||||
for(auto& point_dirty : point_light_dirty)
|
||||
|
||||
for (auto& point_dirty : point_light_dirty)
|
||||
point_dirty = true;
|
||||
|
||||
for(auto& spot_dirty : spot_light_dirty)
|
||||
|
||||
for (auto& spot_dirty : spot_light_dirty)
|
||||
spot_dirty = true;
|
||||
}
|
||||
|
||||
|
||||
/// Invalidates the current environment probe data. This may cause stuttering while the data is regenerated.
|
||||
void reset_environment() {
|
||||
for(auto& probe_dirty : environment_dirty)
|
||||
for (auto& probe_dirty : environment_dirty)
|
||||
probe_dirty = true;
|
||||
}
|
||||
|
||||
|
||||
// shadow
|
||||
GFXTexture* depthTexture = nullptr;
|
||||
GFXFramebuffer* framebuffer = nullptr;
|
||||
|
||||
|
||||
Matrix4x4 lightSpace;
|
||||
Matrix4x4 spotLightSpaces[max_spot_shadows];
|
||||
|
||||
|
||||
GFXTexture* pointLightArray = nullptr;
|
||||
GFXTexture* spotLightArray = nullptr;
|
||||
|
||||
|
||||
bool sun_light_dirty = false;
|
||||
std::array<bool, max_point_shadows> point_light_dirty;
|
||||
std::array<bool, max_spot_shadows> spot_light_dirty;
|
||||
|
||||
int shadow_refresh_timer = 1;
|
||||
int probe_refresh_timer = 1;
|
||||
|
||||
|
||||
// environment
|
||||
std::array<bool, max_environment_probes> environment_dirty;
|
||||
|
||||
|
@ -251,7 +244,8 @@ public:
|
|||
@param cam The camera object.
|
||||
@param pos The position the camera will be viewing the target from.
|
||||
@param target The position to be centered in the camera's view.
|
||||
@note Although this is a look at function, it applies no special attribute to the camera and simply changes it's position and rotation.
|
||||
@note Although this is a look at function, it applies no special attribute to the camera and simply changes it's
|
||||
position and rotation.
|
||||
*/
|
||||
void camera_look_at(Scene& scene, prism::Object cam, prism::float3 pos, prism::float3 target);
|
||||
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
#include "console.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "file.hpp"
|
||||
#include "log.hpp"
|
||||
#include "string_utils.hpp"
|
||||
#include "file.hpp"
|
||||
|
||||
struct registered_command {
|
||||
registered_command(const prism::console::argument_format format, const prism::console::function_ptr function) : expected_format(format), function(function) {}
|
||||
registered_command(const prism::console::argument_format format, const prism::console::function_ptr function)
|
||||
: expected_format(format), function(function) {}
|
||||
|
||||
prism::console::argument_format expected_format;
|
||||
std::function<void(prism::console::arguments)> function;
|
||||
|
@ -19,12 +20,15 @@ static std::unordered_map<std::string, registered_command> registered_commands;
|
|||
|
||||
struct RegisteredVariable {
|
||||
RegisteredVariable(bool& data) : type(prism::console::argument_type::Boolean), data(&data) {}
|
||||
|
||||
RegisteredVariable(float& data) : type(prism::console::argument_type::Float), data(&data) {}
|
||||
|
||||
RegisteredVariable(int& data) : type(prism::console::argument_type::Integer), data(&data) {}
|
||||
|
||||
RegisteredVariable(double& data) : type(prism::console::argument_type::Double), data(&data) {}
|
||||
|
||||
prism::console::argument_type type;
|
||||
|
||||
|
||||
std::variant<bool*, float*, int*, double*> data;
|
||||
};
|
||||
|
||||
|
@ -33,48 +37,51 @@ static std::unordered_map<std::string, RegisteredVariable> registered_variables;
|
|||
void prism::console::load_cfg(const prism::path& path) {
|
||||
auto file = prism::open_file(path);
|
||||
auto stream = file->read_as_stream();
|
||||
for (std::string line; getline( stream, line );) {
|
||||
for (std::string line; getline(stream, line);) {
|
||||
prism::console::parse_and_invoke_command(line);
|
||||
}
|
||||
}
|
||||
|
||||
void prism::console::register_command(const std::string_view name, const prism::console::argument_format expected_format, const prism::console::function_ptr function) {
|
||||
void prism::console::register_command(
|
||||
const std::string_view name,
|
||||
const prism::console::argument_format expected_format,
|
||||
const prism::console::function_ptr function) {
|
||||
registered_commands.try_emplace(name.data(), registered_command(expected_format, function));
|
||||
}
|
||||
|
||||
void prism::console::invoke_command(const std::string_view name, const prism::console::arguments arguments) {
|
||||
for(auto& [command_name, command_data] : registered_commands) {
|
||||
if(command_name == name) {
|
||||
for (auto& [command_name, command_data] : registered_commands) {
|
||||
if (command_name == name) {
|
||||
bool invalid_format = false;
|
||||
|
||||
if(arguments.size() != command_data.expected_format.num_arguments)
|
||||
|
||||
if (arguments.size() != command_data.expected_format.num_arguments)
|
||||
invalid_format = true;
|
||||
|
||||
if(invalid_format) {
|
||||
|
||||
if (invalid_format) {
|
||||
prism::log("Invalid command format!");
|
||||
} else {
|
||||
command_data.function(console::arguments());
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for(auto& [variable_name, variable_data] : registered_variables) {
|
||||
if(variable_name == name) {
|
||||
|
||||
for (auto& [variable_name, variable_data] : registered_variables) {
|
||||
if (variable_name == name) {
|
||||
bool invalid_format = false;
|
||||
|
||||
if(arguments.empty())
|
||||
if (arguments.empty())
|
||||
invalid_format = true;
|
||||
|
||||
if(arguments[0].query_type() != variable_data.type)
|
||||
|
||||
if (arguments[0].query_type() != variable_data.type)
|
||||
invalid_format = true;
|
||||
|
||||
if(invalid_format) {
|
||||
|
||||
if (invalid_format) {
|
||||
prism::log("Wrong or empty variable type!");
|
||||
} else {
|
||||
auto argument = arguments[0];
|
||||
switch(argument.query_type()) {
|
||||
switch (argument.query_type()) {
|
||||
case console::argument_type::Boolean:
|
||||
*std::get<bool*>(variable_data.data) = std::get<bool>(argument.data);
|
||||
break;
|
||||
|
@ -82,11 +89,11 @@ void prism::console::invoke_command(const std::string_view name, const prism::co
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
prism::log("{} is not the name of a valid command or variable!", name.data());
|
||||
}
|
||||
|
||||
|
@ -94,25 +101,25 @@ void prism::console::parse_and_invoke_command(const std::string_view command) {
|
|||
prism::log("> {}", command);
|
||||
|
||||
const auto tokens = tokenize(command, " ");
|
||||
if(tokens.empty())
|
||||
if (tokens.empty())
|
||||
return;
|
||||
|
||||
|
||||
const auto try_parse_argument = [](std::string_view arg) -> std::optional<console_argument> {
|
||||
if(arg == "true") {
|
||||
if (arg == "true") {
|
||||
return console_argument(true);
|
||||
} else if(arg == "false") {
|
||||
} else if (arg == "false") {
|
||||
return console_argument(false);
|
||||
} else if(is_numeric(arg)) {
|
||||
} else if (is_numeric(arg)) {
|
||||
return console_argument(std::stoi(arg.data()));
|
||||
} else {
|
||||
return console_argument(arg);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
std::vector<console_argument> arguments;
|
||||
|
||||
for(int i = 1; i < tokens.size(); i++) {
|
||||
if(auto arg = try_parse_argument(tokens[i]); arg)
|
||||
|
||||
for (int i = 1; i < tokens.size(); i++) {
|
||||
if (auto arg = try_parse_argument(tokens[i]); arg)
|
||||
arguments.push_back(*arg);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,17 +3,17 @@
|
|||
#include <imgui.h>
|
||||
#include <imgui_stdlib.h>
|
||||
|
||||
#include "engine.hpp"
|
||||
#include "shadowpass.hpp"
|
||||
#include "scenecapture.hpp"
|
||||
#include "gfx.hpp"
|
||||
#include "asset.hpp"
|
||||
#include "imgui_utility.hpp"
|
||||
#include "scene.hpp"
|
||||
#include "renderer.hpp"
|
||||
#include "file.hpp"
|
||||
#include "console.hpp"
|
||||
#include "engine.hpp"
|
||||
#include "file.hpp"
|
||||
#include "gfx.hpp"
|
||||
#include "imgui_backend.hpp"
|
||||
#include "imgui_utility.hpp"
|
||||
#include "renderer.hpp"
|
||||
#include "scene.hpp"
|
||||
#include "scenecapture.hpp"
|
||||
#include "shadowpass.hpp"
|
||||
|
||||
struct Options {
|
||||
std::string shader_source_path;
|
||||
|
@ -30,33 +30,33 @@ void draw_asset() {
|
|||
ImGui::Text("Asset References");
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
|
||||
ImGui::BeginChild("asset_child", ImVec2(-1, -1), true);
|
||||
|
||||
for(auto& [path, block] : assetm->reference_blocks) {
|
||||
|
||||
for (auto& [path, block] : assetm->reference_blocks) {
|
||||
ImGui::PushID(&block);
|
||||
|
||||
|
||||
ImGui::Text("- %s has %lu reference(s)", path.string().c_str(), block->references);
|
||||
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor(200, 0, 0));
|
||||
|
||||
if(ImGui::SmallButton("Force unload"))
|
||||
|
||||
if (ImGui::SmallButton("Force unload"))
|
||||
block->references = 0;
|
||||
|
||||
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
void draw_lighting() {
|
||||
if(engine->get_scene() != nullptr) {
|
||||
if (engine->get_scene() != nullptr) {
|
||||
const auto& lights = engine->get_scene()->get_all<Light>();
|
||||
|
||||
if(ImGui::CollapsingHeader("Lights")) {
|
||||
for (auto&[obj, light]: lights) {
|
||||
if (ImGui::CollapsingHeader("Lights")) {
|
||||
for (auto& [obj, light] : lights) {
|
||||
ImGui::PushID(obj);
|
||||
|
||||
ImGui::TextDisabled("%s", engine->get_scene()->get(obj).name.c_str());
|
||||
|
@ -71,9 +71,9 @@ void draw_lighting() {
|
|||
ImGui::Separator();
|
||||
}
|
||||
}
|
||||
|
||||
if(ImGui::CollapsingHeader("Environment")) {
|
||||
for(auto& [obj, probe] : engine->get_scene()->get_all<EnvironmentProbe>()) {
|
||||
|
||||
if (ImGui::CollapsingHeader("Environment")) {
|
||||
for (auto& [obj, probe] : engine->get_scene()->get_all<EnvironmentProbe>()) {
|
||||
ImGui::PushID(obj);
|
||||
|
||||
ImGui::TextDisabled("%s", engine->get_scene()->get(obj).name.c_str());
|
||||
|
@ -88,8 +88,8 @@ void draw_lighting() {
|
|||
}
|
||||
}
|
||||
|
||||
if(ImGui::CollapsingHeader("Materials")) {
|
||||
for (auto& material: assetm->get_all<Material>()) {
|
||||
if (ImGui::CollapsingHeader("Materials")) {
|
||||
for (auto& material : assetm->get_all<Material>()) {
|
||||
ImGui::PushID(material);
|
||||
|
||||
ImGui::TextDisabled("%s", material->path.c_str());
|
||||
|
@ -103,10 +103,10 @@ void draw_lighting() {
|
|||
}
|
||||
}
|
||||
|
||||
if(ImGui::Button("Reload shadows"))
|
||||
if (ImGui::Button("Reload shadows"))
|
||||
engine->get_scene()->reset_shadows();
|
||||
|
||||
if(ImGui::Button("Reload probes"))
|
||||
if (ImGui::Button("Reload probes"))
|
||||
engine->get_scene()->reset_environment();
|
||||
} else {
|
||||
ImGui::TextDisabled("No scene loaded.");
|
||||
|
@ -114,78 +114,77 @@ void draw_lighting() {
|
|||
}
|
||||
|
||||
void draw_renderer() {
|
||||
if(engine->get_scene() != nullptr) {
|
||||
if (engine->get_scene() != nullptr) {
|
||||
ImGui::Text("Budgets");
|
||||
ImGui::Separator();
|
||||
|
||||
|
||||
const auto& lights = engine->get_scene()->get_all<Light>();
|
||||
const auto& probes = engine->get_scene()->get_all<EnvironmentProbe>();
|
||||
const auto& renderables = engine->get_scene()->get_all<Renderable>();
|
||||
|
||||
|
||||
ImGui::ProgressBar("Light Budget", lights.size(), max_scene_lights);
|
||||
ImGui::ProgressBar("Probe Budget", probes.size(), max_environment_probes);
|
||||
|
||||
|
||||
int material_count = 0;
|
||||
for(const auto& [obj, renderable] : renderables) {
|
||||
for(auto& material : renderable.materials) {
|
||||
if(material)
|
||||
for (const auto& [obj, renderable] : renderables) {
|
||||
for (auto& material : renderable.materials) {
|
||||
if (material)
|
||||
material_count++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ImGui::ProgressBar("Material Budget (estimated)", material_count, max_scene_materials);
|
||||
} else {
|
||||
ImGui::TextDisabled("No scene loaded for budgeting.");
|
||||
}
|
||||
|
||||
|
||||
auto targets = engine->get_renderer()->get_all_render_targets();
|
||||
for(auto target : targets) {
|
||||
for (auto target : targets) {
|
||||
ImGui::Text("Frame %i", target->current_frame);
|
||||
ImGui::Text("%i %i", target->extent.width, target->extent.height);
|
||||
ImGui::Image(target->offscreenColorTexture, ImVec2(100, 100));
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
||||
|
||||
ImGui::Text("Performance");
|
||||
ImGui::Separator();
|
||||
|
||||
|
||||
ImGui::Text("FPS: %f", ImGui::GetIO().Framerate);
|
||||
|
||||
|
||||
ImGui::Text("Options");
|
||||
ImGui::Separator();
|
||||
|
||||
|
||||
ImGui::ComboEnum("Display Color Space", &render_options.display_color_space);
|
||||
ImGui::ComboEnum("Tonemapping", &render_options.tonemapping);
|
||||
|
||||
if(ImGui::CollapsingHeader("Tonemapping")) {
|
||||
ImGui::DragFloat("Exposure", &render_options.exposure, 0.1f);
|
||||
ImGui::DragFloat("Min Luminance", &render_options.min_luminance);
|
||||
ImGui::DragFloat("Max Luminance", &render_options.max_luminance);
|
||||
if (ImGui::CollapsingHeader("Tonemapping")) {
|
||||
ImGui::DragFloat("Exposure", &render_options.exposure, 0.1f);
|
||||
ImGui::DragFloat("Min Luminance", &render_options.min_luminance);
|
||||
ImGui::DragFloat("Max Luminance", &render_options.max_luminance);
|
||||
}
|
||||
|
||||
if(ImGui::CollapsingHeader("Depth of Field")) {
|
||||
ImGui::Checkbox("Enable DoF", &render_options.enable_depth_of_field);
|
||||
ImGui::DragFloat("DoF Strength", &render_options.depth_of_field_strength);
|
||||
if (ImGui::CollapsingHeader("Depth of Field")) {
|
||||
ImGui::Checkbox("Enable DoF", &render_options.enable_depth_of_field);
|
||||
ImGui::DragFloat("DoF Strength", &render_options.depth_of_field_strength);
|
||||
}
|
||||
|
||||
bool should_recompile = false;
|
||||
|
||||
if(ImGui::CollapsingHeader("Dynamic Resolution")) {
|
||||
ImGui::Checkbox("Enable Dynamic Resolution", &render_options.dynamic_resolution);
|
||||
if (ImGui::CollapsingHeader("Dynamic Resolution")) {
|
||||
ImGui::Checkbox("Enable Dynamic Resolution", &render_options.dynamic_resolution);
|
||||
|
||||
float render_scale = render_options.render_scale;
|
||||
if (ImGui::DragFloat("Render Scale", &render_scale, 0.1f, 1.0f, 0.1f)
|
||||
&& render_scale > 0.0f) {
|
||||
render_options.render_scale = render_scale;
|
||||
engine->get_renderer()->recreate_all_render_targets();
|
||||
}
|
||||
float render_scale = render_options.render_scale;
|
||||
if (ImGui::DragFloat("Render Scale", &render_scale, 0.1f, 1.0f, 0.1f) && render_scale > 0.0f) {
|
||||
render_options.render_scale = render_scale;
|
||||
engine->get_renderer()->recreate_all_render_targets();
|
||||
}
|
||||
}
|
||||
|
||||
if(ImGui::InputInt("Shadow Resolution", &render_options.shadow_resolution)) {
|
||||
|
||||
if (ImGui::InputInt("Shadow Resolution", &render_options.shadow_resolution)) {
|
||||
engine->get_renderer()->shadow_pass->create_scene_resources(*engine->get_scene());
|
||||
engine->get_scene()->reset_shadows();
|
||||
}
|
||||
|
||||
|
||||
ImGui::Checkbox("Enable AA", &render_options.enable_aa);
|
||||
should_recompile |= ImGui::Checkbox("Enable IBL", &render_options.enable_ibl);
|
||||
should_recompile |= ImGui::Checkbox("Enable Normal Mapping", &render_options.enable_normal_mapping);
|
||||
|
@ -195,8 +194,8 @@ void draw_renderer() {
|
|||
ImGui::Checkbox("Enable Extra Passes", &render_options.enable_extra_passes);
|
||||
ImGui::Checkbox("Enable Frustum Culling", &render_options.enable_frustum_culling);
|
||||
|
||||
if(ImGui::Button("Force recompile materials (needed for some render option changes!)") || should_recompile) {
|
||||
for(auto material : assetm->get_all<Material>()) {
|
||||
if (ImGui::Button("Force recompile materials (needed for some render option changes!)") || should_recompile) {
|
||||
for (auto material : assetm->get_all<Material>()) {
|
||||
material->capture_pipeline = nullptr;
|
||||
material->skinned_pipeline = nullptr;
|
||||
material->static_pipeline = nullptr;
|
||||
|
@ -208,71 +207,72 @@ static inline std::string selected_shader;
|
|||
static inline std::string loaded_shader_string;
|
||||
|
||||
void draw_shader_editor() {
|
||||
if(options.shader_source_path.empty()) {
|
||||
if (options.shader_source_path.empty()) {
|
||||
ImGui::Text("You haven't specified a shader source path yet. Please select one below:");
|
||||
if(ImGui::Button("Select Path")) {
|
||||
if (ImGui::Button("Select Path")) {
|
||||
engine->get_imgui().open_dialog(false, [](std::string path) {
|
||||
// open_dialog() can't select folders yet, so use this as a workaround
|
||||
options.shader_source_path = prism::path(path).parent_path().string();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if(ImGui::BeginCombo("Select", nullptr)) {
|
||||
for(auto& shader : engine->get_renderer()->registered_shaders) {
|
||||
if(ImGui::Selectable(shader.filename.data())) {
|
||||
if (ImGui::BeginCombo("Select", nullptr)) {
|
||||
for (auto& shader : engine->get_renderer()->registered_shaders) {
|
||||
if (ImGui::Selectable(shader.filename.data())) {
|
||||
selected_shader = shader.filename;
|
||||
loaded_shader_string.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
if(!selected_shader.empty()) {
|
||||
if(loaded_shader_string.empty()) {
|
||||
|
||||
if (!selected_shader.empty()) {
|
||||
if (loaded_shader_string.empty()) {
|
||||
prism::path base_shader_path = options.shader_source_path;
|
||||
|
||||
|
||||
shader_compiler.set_include_path(base_shader_path.string());
|
||||
|
||||
|
||||
prism::path shader_path = prism::path(selected_shader);
|
||||
|
||||
auto file = prism::open_file(base_shader_path / shader_path.replace_extension(shader_path.extension().string() + ".glsl"));
|
||||
|
||||
|
||||
auto file = prism::open_file(
|
||||
base_shader_path / shader_path.replace_extension(shader_path.extension().string() + ".glsl"));
|
||||
|
||||
loaded_shader_string = file->read_as_string();
|
||||
}
|
||||
|
||||
|
||||
ImGui::InputTextMultiline("Source", &loaded_shader_string);
|
||||
|
||||
if(ImGui::Button("Reload"))
|
||||
|
||||
if (ImGui::Button("Reload"))
|
||||
engine->get_renderer()->reload_shader(selected_shader, loaded_shader_string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw_debug_ui() {
|
||||
if(ImGui::Begin("General"))
|
||||
if (ImGui::Begin("General"))
|
||||
draw_general();
|
||||
|
||||
ImGui::End();
|
||||
|
||||
if(ImGui::Begin("Lighting"))
|
||||
draw_lighting();
|
||||
|
||||
|
||||
ImGui::End();
|
||||
|
||||
if(ImGui::Begin("Assets"))
|
||||
if (ImGui::Begin("Lighting"))
|
||||
draw_lighting();
|
||||
|
||||
ImGui::End();
|
||||
|
||||
if (ImGui::Begin("Assets"))
|
||||
draw_asset();
|
||||
|
||||
ImGui::End();
|
||||
|
||||
if(ImGui::Begin("Rendering"))
|
||||
|
||||
if (ImGui::Begin("Rendering"))
|
||||
draw_renderer();
|
||||
|
||||
|
||||
ImGui::End();
|
||||
|
||||
if(ImGui::Begin("Shader Editor"))
|
||||
|
||||
if (ImGui::Begin("Shader Editor"))
|
||||
draw_shader_editor();
|
||||
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
|
@ -311,14 +311,14 @@ void draw_console() {
|
|||
|
||||
const bool input_return = ImGui::InputText("##console_input", &console_input, ImGuiInputTextFlags_EnterReturnsTrue);
|
||||
|
||||
if(input_return)
|
||||
if (input_return)
|
||||
ImGui::SetKeyboardFocusHere(-1);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
const bool button_return = ImGui::Button("Submit");
|
||||
|
||||
if(input_return || button_return) {
|
||||
if (input_return || button_return) {
|
||||
prism::console::parse_and_invoke_command(console_input);
|
||||
console_input.clear();
|
||||
}
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
#include "engine.hpp"
|
||||
|
||||
#include <imgui.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <utility>
|
||||
#include <imgui.h>
|
||||
|
||||
#include "scene.hpp"
|
||||
#include "console.hpp"
|
||||
#include "log.hpp"
|
||||
#include "asset.hpp"
|
||||
#include "json_conversions.hpp"
|
||||
#include "app.hpp"
|
||||
#include "assertions.hpp"
|
||||
#include "renderer.hpp"
|
||||
#include "asset.hpp"
|
||||
#include "console.hpp"
|
||||
#include "debug.hpp"
|
||||
#include "gfx.hpp"
|
||||
#include "imgui_backend.hpp"
|
||||
#include "debug.hpp"
|
||||
#include "timer.hpp"
|
||||
#include "physics.hpp"
|
||||
#include "input.hpp"
|
||||
#include "json_conversions.hpp"
|
||||
#include "log.hpp"
|
||||
#include "physics.hpp"
|
||||
#include "renderer.hpp"
|
||||
#include "scene.hpp"
|
||||
#include "timer.hpp"
|
||||
|
||||
// TODO: remove these in the future
|
||||
#include "shadowpass.hpp"
|
||||
#include "scenecapture.hpp"
|
||||
#include "shadowpass.hpp"
|
||||
|
||||
using prism::engine;
|
||||
|
||||
|
@ -29,7 +29,7 @@ engine::engine(const int argc, char* argv[]) {
|
|||
log("Prism Engine loading...");
|
||||
|
||||
console::register_command("echo", console::argument_format(1), [](const console::arguments& args) {
|
||||
log(std::get<std::string>(args[0].data));
|
||||
log(std::get<std::string>(args[0].data));
|
||||
});
|
||||
|
||||
console::register_command("platform_info", console::argument_format(0), [this](const console::arguments&) {
|
||||
|
@ -51,7 +51,7 @@ engine::engine(const int argc, char* argv[]) {
|
|||
console::register_variable("rs_frustum_culling", render_options.enable_frustum_culling);
|
||||
|
||||
console::register_command("rebuild_mat", console::argument_format(0), [this](const console::arguments&) {
|
||||
for(auto material : assetm->get_all<Material>()) {
|
||||
for (auto material : assetm->get_all<Material>()) {
|
||||
material->capture_pipeline = nullptr;
|
||||
material->skinned_pipeline = nullptr;
|
||||
material->static_pipeline = nullptr;
|
||||
|
@ -62,7 +62,7 @@ engine::engine(const int argc, char* argv[]) {
|
|||
quit();
|
||||
});
|
||||
|
||||
for(int i = 0; i < argc; i++)
|
||||
for (int i = 0; i < argc; i++)
|
||||
command_line_arguments.emplace_back(argv[i]);
|
||||
|
||||
input = std::make_unique<input_system>();
|
||||
|
@ -78,7 +78,7 @@ void engine::set_app(prism::app* p_app) {
|
|||
|
||||
this->current_app = p_app;
|
||||
|
||||
if(platform::supports_feature(PlatformFeature::Windowing) && get_app()->is_multimodal()) {
|
||||
if (platform::supports_feature(PlatformFeature::Windowing) && get_app()->is_multimodal()) {
|
||||
ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
|
||||
}
|
||||
|
||||
|
@ -102,12 +102,12 @@ bool engine::is_paused() const {
|
|||
}
|
||||
|
||||
void engine::quit() {
|
||||
if(!windows.empty())
|
||||
if (!windows.empty())
|
||||
windows[0]->quit_requested = true;
|
||||
}
|
||||
|
||||
bool engine::is_quitting() const {
|
||||
if(!windows.empty())
|
||||
if (!windows.empty())
|
||||
return windows[0]->quit_requested;
|
||||
|
||||
return false;
|
||||
|
@ -128,7 +128,7 @@ GFX* engine::get_gfx() {
|
|||
}
|
||||
|
||||
prism::input_system* engine::get_input() {
|
||||
return input.get();
|
||||
return input.get();
|
||||
}
|
||||
|
||||
prism::renderer* engine::get_renderer() {
|
||||
|
@ -141,9 +141,9 @@ Physics* engine::get_physics() {
|
|||
|
||||
Scene* engine::create_empty_scene() {
|
||||
auto scene = std::make_unique<Scene>();
|
||||
|
||||
|
||||
setup_scene(*scene);
|
||||
|
||||
|
||||
scenes.push_back(std::move(scene));
|
||||
current_scene = scenes.back().get();
|
||||
|
||||
|
@ -154,7 +154,7 @@ Scene* engine::load_scene(const prism::path& path) {
|
|||
Expects(!path.empty());
|
||||
|
||||
auto file = prism::open_file(path);
|
||||
if(!file.has_value()) {
|
||||
if (!file.has_value()) {
|
||||
prism::log("Failed to load scene from {}!", path.string());
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -166,8 +166,8 @@ Scene* engine::load_scene(const prism::path& path) {
|
|||
|
||||
std::map<Object, std::string> parentQueue;
|
||||
|
||||
for(auto& obj : j["objects"]) {
|
||||
if(obj.contains("prefabPath")) {
|
||||
for (auto& obj : j["objects"]) {
|
||||
if (obj.contains("prefabPath")) {
|
||||
Object o = add_prefab(*scene, prism::game_domain / obj["prefabPath"].get<std::string_view>());
|
||||
|
||||
scene->get(o).name = obj["name"];
|
||||
|
@ -179,30 +179,30 @@ Scene* engine::load_scene(const prism::path& path) {
|
|||
} else {
|
||||
auto o = load_object(*scene, obj);
|
||||
|
||||
if(obj.contains("parent"))
|
||||
if (obj.contains("parent"))
|
||||
parentQueue[o] = obj["parent"];
|
||||
}
|
||||
}
|
||||
|
||||
for(auto& [obj, toParent] : parentQueue)
|
||||
for (auto& [obj, toParent] : parentQueue)
|
||||
scene->get<Data>(obj).parent = scene->find_object(toParent);
|
||||
|
||||
|
||||
setup_scene(*scene);
|
||||
|
||||
|
||||
scenes.push_back(std::move(scene));
|
||||
current_scene = scenes.back().get();
|
||||
path_to_scene[path.string()] = scenes.back().get();
|
||||
|
||||
|
||||
return scenes.back().get();
|
||||
}
|
||||
|
||||
void engine::save_scene(const std::string_view path) {
|
||||
Expects(!path.empty());
|
||||
|
||||
|
||||
nlohmann::json j;
|
||||
|
||||
for(auto& obj : current_scene->get_objects()) {
|
||||
if(!current_scene->get(obj).editor_object)
|
||||
for (auto& obj : current_scene->get_objects()) {
|
||||
if (!current_scene->get(obj).editor_object)
|
||||
j["objects"].push_back(save_object(obj));
|
||||
}
|
||||
|
||||
|
@ -213,7 +213,7 @@ void engine::save_scene(const std::string_view path) {
|
|||
AnimationChannel engine::load_animation(nlohmann::json a) {
|
||||
AnimationChannel animation;
|
||||
|
||||
for(auto& kf : a["frames"]) {
|
||||
for (auto& kf : a["frames"]) {
|
||||
PositionKeyFrame keyframe;
|
||||
keyframe.time = kf["time"];
|
||||
keyframe.value = kf["value"];
|
||||
|
@ -228,7 +228,7 @@ Animation engine::load_animation(const prism::path& path) {
|
|||
Expects(!path.empty());
|
||||
|
||||
auto file = prism::open_file(path, true);
|
||||
if(!file.has_value()) {
|
||||
if (!file.has_value()) {
|
||||
prism::log("Failed to load animation from {}!", path.string());
|
||||
return {};
|
||||
}
|
||||
|
@ -241,7 +241,7 @@ Animation engine::load_animation(const prism::path& path) {
|
|||
unsigned int num_channels;
|
||||
file->read(&num_channels);
|
||||
|
||||
for(unsigned int i = 0; i < num_channels; i++) {
|
||||
for (unsigned int i = 0; i < num_channels; i++) {
|
||||
AnimationChannel channel;
|
||||
|
||||
file->read_string(channel.id);
|
||||
|
@ -249,7 +249,7 @@ Animation engine::load_animation(const prism::path& path) {
|
|||
unsigned int num_positions;
|
||||
file->read(&num_positions);
|
||||
|
||||
for(unsigned int j = 0; j < num_positions; j++) {
|
||||
for (unsigned int j = 0; j < num_positions; j++) {
|
||||
PositionKeyFrame key;
|
||||
file->read(&key);
|
||||
|
||||
|
@ -259,7 +259,7 @@ Animation engine::load_animation(const prism::path& path) {
|
|||
unsigned int num_rotations;
|
||||
file->read(&num_rotations);
|
||||
|
||||
for(unsigned int j = 0; j < num_rotations; j++) {
|
||||
for (unsigned int j = 0; j < num_rotations; j++) {
|
||||
RotationKeyFrame key;
|
||||
file->read(&key);
|
||||
|
||||
|
@ -269,7 +269,7 @@ Animation engine::load_animation(const prism::path& path) {
|
|||
unsigned int num_scales;
|
||||
file->read(&num_scales);
|
||||
|
||||
for(unsigned int j = 0; j < num_scales; j++) {
|
||||
for (unsigned int j = 0; j < num_scales; j++) {
|
||||
ScaleKeyFrame key;
|
||||
file->read(&key);
|
||||
|
||||
|
@ -288,7 +288,7 @@ void engine::load_cutscene(const prism::path& path) {
|
|||
cutscene = std::make_unique<Cutscene>();
|
||||
|
||||
auto file = prism::open_file(path);
|
||||
if(!file.has_value()) {
|
||||
if (!file.has_value()) {
|
||||
prism::log("Failed to load cutscene from {}!", path.string());
|
||||
return;
|
||||
}
|
||||
|
@ -296,36 +296,36 @@ void engine::load_cutscene(const prism::path& path) {
|
|||
nlohmann::json j;
|
||||
file->read_as_stream() >> j;
|
||||
|
||||
for(auto& s : j["shots"]) {
|
||||
for (auto& s : j["shots"]) {
|
||||
Shot shot;
|
||||
shot.begin = s["begin"];
|
||||
shot.length = s["end"];
|
||||
|
||||
for(auto& animation : s["animations"]) {
|
||||
for (auto& animation : s["animations"]) {
|
||||
shot.channels.push_back(load_animation(animation));
|
||||
}
|
||||
|
||||
if(path_to_scene.count(s["scene"])) {
|
||||
if (path_to_scene.count(s["scene"])) {
|
||||
shot.scene = path_to_scene[s["scene"]];
|
||||
|
||||
// try to find main camera
|
||||
auto [obj, cam] = shot.scene->get_all<Camera>()[0];
|
||||
|
||||
for(auto& anim : shot.channels) {
|
||||
if(anim.target == NullObject)
|
||||
for (auto& anim : shot.channels) {
|
||||
if (anim.target == NullObject)
|
||||
anim.target = obj;
|
||||
}
|
||||
} else {
|
||||
load_scene(prism::root_path(path) / s["scene"].get<std::string_view>());
|
||||
|
||||
if(get_scene() == nullptr)
|
||||
if (get_scene() == nullptr)
|
||||
create_empty_scene();
|
||||
|
||||
|
||||
auto cameraObj = get_scene()->add_object();
|
||||
get_scene()->add<Camera>(cameraObj);
|
||||
|
||||
for(auto& anim : shot.channels) {
|
||||
if(anim.target == NullObject)
|
||||
for (auto& anim : shot.channels) {
|
||||
if (anim.target == NullObject)
|
||||
anim.target = cameraObj;
|
||||
}
|
||||
|
||||
|
@ -342,13 +342,13 @@ void engine::save_cutscene(const std::string_view path) {
|
|||
|
||||
nlohmann::json j;
|
||||
|
||||
for(auto& shot : cutscene->shots) {
|
||||
for (auto& shot : cutscene->shots) {
|
||||
nlohmann::json s;
|
||||
s["begin"] = shot.begin;
|
||||
s["end"] = shot.length;
|
||||
|
||||
for(auto& [scene_path, scene] : path_to_scene) {
|
||||
if(shot.scene == scene)
|
||||
for (auto& [scene_path, scene] : path_to_scene) {
|
||||
if (shot.scene == scene)
|
||||
s["scene"] = scene_path;
|
||||
}
|
||||
|
||||
|
@ -361,9 +361,9 @@ void engine::save_cutscene(const std::string_view path) {
|
|||
|
||||
prism::Object engine::add_prefab(Scene& scene, const prism::path& path, const std::string_view override_name) {
|
||||
Expects(!path.empty());
|
||||
|
||||
|
||||
auto file = prism::open_file(path);
|
||||
if(!file.has_value()) {
|
||||
if (!file.has_value()) {
|
||||
prism::log("Failed to load prefab from {}!", path.string());
|
||||
return NullObject;
|
||||
}
|
||||
|
@ -375,20 +375,20 @@ prism::Object engine::add_prefab(Scene& scene, const prism::path& path, const st
|
|||
|
||||
std::map<Object, std::string> parent_queue;
|
||||
|
||||
for(const auto& obj : j["objects"]) {
|
||||
for (const auto& obj : j["objects"]) {
|
||||
auto o = load_object(scene, obj);
|
||||
|
||||
if(obj.contains("parent")) {
|
||||
if (obj.contains("parent")) {
|
||||
parent_queue[o] = obj["parent"];
|
||||
} else {
|
||||
root_node = o;
|
||||
}
|
||||
}
|
||||
|
||||
for(auto& [obj, parent_name] : parent_queue)
|
||||
for (auto& [obj, parent_name] : parent_queue)
|
||||
scene.get(obj).parent = scene.find_object(parent_name);
|
||||
|
||||
if(!override_name.empty() && root_node != NullObject)
|
||||
if (!override_name.empty() && root_node != NullObject)
|
||||
scene.get(root_node).name = override_name;
|
||||
|
||||
return root_node;
|
||||
|
@ -397,11 +397,11 @@ prism::Object engine::add_prefab(Scene& scene, const prism::path& path, const st
|
|||
void engine::save_prefab(const Object root, const std::string_view path) {
|
||||
Expects(root != NullObject);
|
||||
Expects(!path.empty());
|
||||
|
||||
|
||||
nlohmann::json j;
|
||||
|
||||
for(auto& obj : current_scene->get_objects()) {
|
||||
if(!current_scene->get(obj).editor_object)
|
||||
for (auto& obj : current_scene->get_objects()) {
|
||||
if (!current_scene->get(obj).editor_object)
|
||||
j["objects"].push_back(save_object(obj));
|
||||
}
|
||||
|
||||
|
@ -417,7 +417,7 @@ void engine::add_window(void* native_handle, const platform::window_ptr window_p
|
|||
|
||||
window->identifier = window_ptr;
|
||||
|
||||
if(platform::is_main_window(window_ptr)) {
|
||||
if (platform::is_main_window(window_ptr)) {
|
||||
current_renderer = std::make_unique<prism::renderer>(gfx);
|
||||
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
|
@ -446,7 +446,7 @@ void engine::resize(const platform::window_ptr identifier, const prism::Extent e
|
|||
return;
|
||||
|
||||
window->extent = extent;
|
||||
|
||||
|
||||
const auto drawable_extent = platform::get_window_drawable_size(identifier);
|
||||
|
||||
gfx->recreate_view(identifier, drawable_extent.width, drawable_extent.height);
|
||||
|
@ -462,37 +462,37 @@ void engine::move(const platform::window_ptr identifier) {
|
|||
void engine::process_key_down(const unsigned int keyCode) {
|
||||
Expects(keyCode >= 0);
|
||||
|
||||
if(input->is_text_input() && !input->get_allowable_text_button(keyCode))
|
||||
if (input->is_text_input() && !input->get_allowable_text_button(keyCode))
|
||||
return;
|
||||
|
||||
imgui->process_key_down(keyCode);
|
||||
|
||||
if(keyCode == platform::get_keycode(debug_button) && !ImGui::GetIO().WantTextInput)
|
||||
if (keyCode == platform::get_keycode(debug_button) && !ImGui::GetIO().WantTextInput)
|
||||
debug_enabled = !debug_enabled;
|
||||
|
||||
if(keyCode == platform::get_keycode(InputButton::C))
|
||||
if (keyCode == platform::get_keycode(InputButton::C))
|
||||
console_enabled = !console_enabled;
|
||||
|
||||
if(keyCode == platform::get_keycode(InputButton::Backspace))
|
||||
if (keyCode == platform::get_keycode(InputButton::Backspace))
|
||||
ui_enabled = !ui_enabled;
|
||||
}
|
||||
|
||||
void engine::process_key_up(const unsigned int keyCode) {
|
||||
Expects(keyCode >= 0);
|
||||
|
||||
|
||||
imgui->process_key_up(keyCode);
|
||||
}
|
||||
|
||||
void engine::process_mouse_down(const int button, const prism::Offset) {
|
||||
imgui->process_mouse_down(button);
|
||||
imgui->process_mouse_down(button);
|
||||
}
|
||||
|
||||
void engine::calculate_bone(Mesh& mesh, const Mesh::Part& part, Bone& bone, const Bone* parent_bone) {
|
||||
if(part.offset_matrices.empty())
|
||||
if (part.offset_matrices.empty())
|
||||
return;
|
||||
|
||||
Matrix4x4 parent_matrix;
|
||||
if(parent_bone != nullptr)
|
||||
if (parent_bone != nullptr)
|
||||
parent_matrix = parent_bone->local_transform;
|
||||
|
||||
Matrix4x4 local = prism::translate(Matrix4x4(), bone.position);
|
||||
|
@ -503,15 +503,15 @@ void engine::calculate_bone(Mesh& mesh, const Mesh::Part& part, Bone& bone, cons
|
|||
|
||||
bone.final_transform = mesh.global_inverse_transformation * bone.local_transform * part.offset_matrices[bone.index];
|
||||
|
||||
for(auto& b : mesh.bones) {
|
||||
if(b.parent != nullptr && b.parent->index == bone.index)
|
||||
for (auto& b : mesh.bones) {
|
||||
if (b.parent != nullptr && b.parent->index == bone.index)
|
||||
calculate_bone(mesh, part, b, &bone);
|
||||
}
|
||||
}
|
||||
|
||||
void engine::calculate_object(Scene& scene, Object object, const Object parent_object) {
|
||||
Matrix4x4 parent_matrix;
|
||||
if(parent_object != NullObject)
|
||||
if (parent_object != NullObject)
|
||||
parent_matrix = scene.get<Transform>(parent_object).model;
|
||||
|
||||
auto& transform = scene.get<Transform>(object);
|
||||
|
@ -522,40 +522,47 @@ void engine::calculate_object(Scene& scene, Object object, const Object parent_o
|
|||
|
||||
transform.model = parent_matrix * local;
|
||||
|
||||
if(scene.has<Renderable>(object)) {
|
||||
if (scene.has<Renderable>(object)) {
|
||||
auto& mesh = scene.get<Renderable>(object);
|
||||
|
||||
if(mesh.mesh && !mesh.mesh->bones.empty()) {
|
||||
if(mesh.temp_bone_data.empty())
|
||||
if (mesh.mesh && !mesh.mesh->bones.empty()) {
|
||||
if (mesh.temp_bone_data.empty())
|
||||
mesh.temp_bone_data.resize(mesh.mesh->bones.size());
|
||||
|
||||
for(auto& part : mesh.mesh->parts) {
|
||||
if(scene.get(object).parent != NullObject && scene.has<Renderable>(scene.get(object).parent) && !scene.get<Renderable>(scene.get(object).parent).mesh->bones.empty()) {
|
||||
for(auto [i, ourBone] : utility::enumerate(mesh.mesh->bones)) {
|
||||
for(auto& theirBone : scene.get<Renderable>(scene.get(object).parent).mesh->bones) {
|
||||
if(ourBone.name == theirBone.name)
|
||||
mesh.temp_bone_data[i] = mesh.mesh->global_inverse_transformation * theirBone.local_transform * part.offset_matrices[ourBone.index];
|
||||
|
||||
for (auto& part : mesh.mesh->parts) {
|
||||
if (scene.get(object).parent != NullObject && scene.has<Renderable>(scene.get(object).parent) &&
|
||||
!scene.get<Renderable>(scene.get(object).parent).mesh->bones.empty()) {
|
||||
for (auto [i, ourBone] : utility::enumerate(mesh.mesh->bones)) {
|
||||
for (auto& theirBone : scene.get<Renderable>(scene.get(object).parent).mesh->bones) {
|
||||
if (ourBone.name == theirBone.name)
|
||||
mesh.temp_bone_data[i] = mesh.mesh->global_inverse_transformation *
|
||||
theirBone.local_transform *
|
||||
part.offset_matrices[ourBone.index];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
calculate_bone(*mesh.mesh.handle, part, *mesh.mesh->root_bone);
|
||||
|
||||
for(auto [i, bone] : utility::enumerate(mesh.temp_bone_data))
|
||||
for (auto [i, bone] : utility::enumerate(mesh.temp_bone_data))
|
||||
mesh.temp_bone_data[i] = mesh.mesh->bones[i].final_transform;
|
||||
}
|
||||
|
||||
gfx->copy_buffer(part.bone_batrix_buffer, mesh.temp_bone_data.data(), 0, mesh.temp_bone_data.size() * sizeof(Matrix4x4));
|
||||
gfx->copy_buffer(
|
||||
part.bone_batrix_buffer,
|
||||
mesh.temp_bone_data.data(),
|
||||
0,
|
||||
mesh.temp_bone_data.size() * sizeof(Matrix4x4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(auto& child : scene.children_of(object))
|
||||
for (auto& child : scene.children_of(object))
|
||||
calculate_object(scene, child, object);
|
||||
}
|
||||
|
||||
Shot* engine::get_shot(const float time) const {
|
||||
for(auto& shot : cutscene->shots) {
|
||||
if(time >= shot.begin && time <= (shot.begin + shot.length))
|
||||
for (auto& shot : cutscene->shots) {
|
||||
if (time >= shot.begin && time <= (shot.begin + shot.length))
|
||||
return &shot;
|
||||
}
|
||||
|
||||
|
@ -566,32 +573,35 @@ void engine::update_animation_channel(Scene& scene, const AnimationChannel& chan
|
|||
{
|
||||
int keyframeIndex = -1;
|
||||
int i = 0;
|
||||
for(auto& frame : channel.positions) {
|
||||
if(time >= frame.time)
|
||||
for (auto& frame : channel.positions) {
|
||||
if (time >= frame.time)
|
||||
keyframeIndex = i;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
if(keyframeIndex != -1) {
|
||||
if (keyframeIndex != -1) {
|
||||
prism::float3* targetVec = nullptr;
|
||||
if(channel.bone != nullptr)
|
||||
if (channel.bone != nullptr)
|
||||
targetVec = &channel.bone->position;
|
||||
|
||||
if(channel.target != NullObject && scene.has<Data>(channel.target))
|
||||
if (channel.target != NullObject && scene.has<Data>(channel.target))
|
||||
targetVec = &scene.get<Transform>(channel.target).position;
|
||||
|
||||
auto& startFrame = channel.positions[keyframeIndex];
|
||||
|
||||
int endFrameIndex = keyframeIndex + 1;
|
||||
if(endFrameIndex > channel.positions.size() - 1) {
|
||||
if(targetVec != nullptr)
|
||||
if (endFrameIndex > channel.positions.size() - 1) {
|
||||
if (targetVec != nullptr)
|
||||
*targetVec = startFrame.value;
|
||||
} else {
|
||||
auto& endFrame = channel.positions[endFrameIndex];
|
||||
|
||||
if(targetVec != nullptr)
|
||||
*targetVec = lerp(startFrame.value, endFrame.value, (float)(time - startFrame.time) / (float)(endFrame.time - startFrame.time));
|
||||
if (targetVec != nullptr)
|
||||
*targetVec = lerp(
|
||||
startFrame.value,
|
||||
endFrame.value,
|
||||
(float)(time - startFrame.time) / (float)(endFrame.time - startFrame.time));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -599,29 +609,32 @@ void engine::update_animation_channel(Scene& scene, const AnimationChannel& chan
|
|||
{
|
||||
int keyframeIndex = -1;
|
||||
int i = 0;
|
||||
for(auto& frame : channel.rotations) {
|
||||
if(time >= frame.time)
|
||||
for (auto& frame : channel.rotations) {
|
||||
if (time >= frame.time)
|
||||
keyframeIndex = i;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
if(keyframeIndex != -1) {
|
||||
if (keyframeIndex != -1) {
|
||||
Quaternion* targetVec = nullptr;
|
||||
if(channel.bone != nullptr)
|
||||
if (channel.bone != nullptr)
|
||||
targetVec = &channel.bone->rotation;
|
||||
|
||||
auto& startFrame = channel.rotations[keyframeIndex];
|
||||
|
||||
int endFrameIndex = keyframeIndex + 1;
|
||||
if(endFrameIndex > channel.rotations.size() - 1) {
|
||||
if(targetVec != nullptr)
|
||||
if (endFrameIndex > channel.rotations.size() - 1) {
|
||||
if (targetVec != nullptr)
|
||||
*targetVec = startFrame.value;
|
||||
} else {
|
||||
auto& endFrame = channel.rotations[endFrameIndex];
|
||||
|
||||
if(targetVec != nullptr)
|
||||
*targetVec = lerp(startFrame.value, endFrame.value, (float)(time - startFrame.time) / (float)(endFrame.time - startFrame.time));
|
||||
if (targetVec != nullptr)
|
||||
*targetVec = lerp(
|
||||
startFrame.value,
|
||||
endFrame.value,
|
||||
(float)(time - startFrame.time) / (float)(endFrame.time - startFrame.time));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -629,10 +642,10 @@ void engine::update_animation_channel(Scene& scene, const AnimationChannel& chan
|
|||
|
||||
void engine::update_cutscene(const float time) {
|
||||
Shot* currentShot = get_shot(time);
|
||||
if(currentShot != nullptr) {
|
||||
if (currentShot != nullptr) {
|
||||
current_scene = currentShot->scene;
|
||||
|
||||
for(auto& channel : currentShot->channels)
|
||||
for (auto& channel : currentShot->channels)
|
||||
update_animation_channel(*current_scene, channel, time);
|
||||
} else {
|
||||
current_scene = nullptr;
|
||||
|
@ -640,14 +653,14 @@ void engine::update_cutscene(const float time) {
|
|||
}
|
||||
|
||||
void engine::update_animation(const Animation& anim, const float time) {
|
||||
for(const auto& channel : anim.channels)
|
||||
for (const auto& channel : anim.channels)
|
||||
update_animation_channel(*current_scene, channel, time);
|
||||
}
|
||||
|
||||
void engine::begin_frame(const float delta_time) {
|
||||
imgui->begin_frame(delta_time);
|
||||
|
||||
if(ui_enabled) {
|
||||
if (ui_enabled) {
|
||||
if (debug_enabled)
|
||||
draw_debug_ui();
|
||||
|
||||
|
@ -655,7 +668,7 @@ void engine::begin_frame(const float delta_time) {
|
|||
draw_console();
|
||||
}
|
||||
|
||||
if(current_app != nullptr)
|
||||
if (current_app != nullptr)
|
||||
current_app->begin_frame();
|
||||
}
|
||||
|
||||
|
@ -668,40 +681,40 @@ const int frame_delay_between_resolution_change = 60;
|
|||
|
||||
void engine::update(const float delta_time) {
|
||||
const float ideal_delta_time = 0.01667f;
|
||||
|
||||
if(render_options.dynamic_resolution) {
|
||||
|
||||
if (render_options.dynamic_resolution) {
|
||||
frame_delay++;
|
||||
|
||||
if(frame_delay >= frame_delay_between_resolution_change) {
|
||||
if(delta_time > ideal_delta_time) {
|
||||
|
||||
if (frame_delay >= frame_delay_between_resolution_change) {
|
||||
if (delta_time > ideal_delta_time) {
|
||||
render_options.render_scale -= 0.1f;
|
||||
|
||||
|
||||
render_options.render_scale = std::fmax(render_options.render_scale, 0.1f);
|
||||
} else {
|
||||
render_options.render_scale += 0.1f;
|
||||
|
||||
|
||||
render_options.render_scale = std::fmin(render_options.render_scale, 1.0f);
|
||||
}
|
||||
|
||||
|
||||
frame_delay = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for(auto& timer : timers) {
|
||||
if(!paused || (paused && timer->continue_during_pause))
|
||||
|
||||
for (auto& timer : timers) {
|
||||
if (!paused || (paused && timer->continue_during_pause))
|
||||
timer->current_time += delta_time;
|
||||
|
||||
if(timer->current_time >= timer->duration) {
|
||||
if (timer->current_time >= timer->duration) {
|
||||
timer->callback();
|
||||
|
||||
timer->current_time = 0.0f;
|
||||
|
||||
if(timer->remove_on_trigger)
|
||||
if (timer->remove_on_trigger)
|
||||
timers_to_remove.push_back(timer);
|
||||
}
|
||||
}
|
||||
|
||||
for(auto& timer : timers_to_remove)
|
||||
for (auto& timer : timers_to_remove)
|
||||
utility::erase(timers, timer);
|
||||
|
||||
timers_to_remove.clear();
|
||||
|
@ -710,58 +723,62 @@ void engine::update(const float delta_time) {
|
|||
|
||||
current_app->update(delta_time);
|
||||
|
||||
if(cutscene != nullptr && play_cutscene && !paused) {
|
||||
if (cutscene != nullptr && play_cutscene && !paused) {
|
||||
update_cutscene(current_cutscene_time);
|
||||
|
||||
current_cutscene_time += delta_time;
|
||||
}
|
||||
|
||||
if(current_scene != nullptr) {
|
||||
if(update_physics && !paused)
|
||||
if (current_scene != nullptr) {
|
||||
if (update_physics && !paused)
|
||||
physics->update(delta_time);
|
||||
|
||||
for(auto& target : animation_targets) {
|
||||
if((target.current_time * target.animation.ticks_per_second) > target.animation.duration) {
|
||||
if(target.looping) {
|
||||
for (auto& target : animation_targets) {
|
||||
if ((target.current_time * target.animation.ticks_per_second) > target.animation.duration) {
|
||||
if (target.looping) {
|
||||
target.current_time = 0.0f;
|
||||
} else {
|
||||
utility::erase(animation_targets, target);
|
||||
}
|
||||
} else {
|
||||
update_animation(target.animation, target.current_time * target.animation.ticks_per_second);
|
||||
|
||||
|
||||
target.current_time += delta_time * target.animation_speed_modifier;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
update_scene(*current_scene);
|
||||
}
|
||||
|
||||
|
||||
assetm->perform_cleanup();
|
||||
}
|
||||
|
||||
void engine::update_scene(Scene& scene) {
|
||||
for(auto& obj : scene.get_objects()) {
|
||||
if(scene.get(obj).parent == NullObject)
|
||||
for (auto& obj : scene.get_objects()) {
|
||||
if (scene.get(obj).parent == NullObject)
|
||||
calculate_object(scene, obj);
|
||||
}
|
||||
}
|
||||
|
||||
void engine::render(const platform::window_ptr index) {
|
||||
auto window = get_window(index);
|
||||
if(window == nullptr)
|
||||
if (window == nullptr)
|
||||
return;
|
||||
|
||||
|
||||
GFXCommandBuffer* commandbuffer = gfx->acquire_command_buffer(true);
|
||||
|
||||
if(platform::is_main_window(index)) {
|
||||
|
||||
if (platform::is_main_window(index)) {
|
||||
imgui->render();
|
||||
|
||||
|
||||
current_app->render(commandbuffer);
|
||||
}
|
||||
|
||||
if(current_renderer != nullptr)
|
||||
current_renderer->render(commandbuffer, current_app->wants_no_scene_rendering() ? nullptr : current_scene, *window->render_target, index);
|
||||
if (current_renderer != nullptr)
|
||||
current_renderer->render(
|
||||
commandbuffer,
|
||||
current_app->wants_no_scene_rendering() ? nullptr : current_scene,
|
||||
*window->render_target,
|
||||
index);
|
||||
|
||||
gfx->submit(commandbuffer, index);
|
||||
}
|
||||
|
@ -776,7 +793,7 @@ Scene* engine::get_scene() {
|
|||
|
||||
Scene* engine::get_scene(const std::string_view name) {
|
||||
Expects(!name.empty());
|
||||
|
||||
|
||||
return path_to_scene[name.data()];
|
||||
}
|
||||
|
||||
|
@ -785,8 +802,8 @@ void engine::set_current_scene(Scene* scene) {
|
|||
}
|
||||
|
||||
std::string_view engine::get_scene_path() const {
|
||||
for(auto& [path, scene] : path_to_scene) {
|
||||
if(scene == this->current_scene)
|
||||
for (auto& [path, scene] : path_to_scene) {
|
||||
if (scene == this->current_scene)
|
||||
return path;
|
||||
}
|
||||
|
||||
|
@ -801,18 +818,18 @@ void engine::on_remove(Object object) {
|
|||
|
||||
void engine::play_animation(Animation animation, Object object, bool looping) {
|
||||
Expects(object != NullObject);
|
||||
|
||||
if(!current_scene->has<Renderable>(object))
|
||||
|
||||
if (!current_scene->has<Renderable>(object))
|
||||
return;
|
||||
|
||||
|
||||
AnimationTarget target;
|
||||
target.animation = std::move(animation);
|
||||
target.target = object;
|
||||
target.looping = looping;
|
||||
|
||||
for(auto& channel : target.animation.channels) {
|
||||
for(auto& bone : current_scene->get<Renderable>(object).mesh->bones) {
|
||||
if(channel.id == bone.name)
|
||||
for (auto& channel : target.animation.channels) {
|
||||
for (auto& bone : current_scene->get<Renderable>(object).mesh->bones) {
|
||||
if (channel.id == bone.name)
|
||||
channel.bone = &bone;
|
||||
}
|
||||
}
|
||||
|
@ -821,15 +838,15 @@ void engine::play_animation(Animation animation, Object object, bool looping) {
|
|||
}
|
||||
|
||||
void engine::set_animation_speed_modifier(Object target, float modifier) {
|
||||
for(auto& animation : animation_targets) {
|
||||
if(animation.target == target)
|
||||
for (auto& animation : animation_targets) {
|
||||
if (animation.target == target)
|
||||
animation.animation_speed_modifier = modifier;
|
||||
}
|
||||
}
|
||||
|
||||
void engine::stop_animation(Object target) {
|
||||
for(auto& animation : animation_targets) {
|
||||
if(animation.target == target)
|
||||
for (auto& animation : animation_targets) {
|
||||
if (animation.target == target)
|
||||
utility::erase(animation_targets, animation);
|
||||
}
|
||||
}
|
||||
|
@ -840,10 +857,10 @@ void engine::setup_scene(Scene& scene) {
|
|||
scene.on_remove = [this](Object obj) {
|
||||
on_remove(obj);
|
||||
};
|
||||
|
||||
|
||||
get_renderer()->shadow_pass->create_scene_resources(scene);
|
||||
get_renderer()->scene_capture->create_scene_resources(scene);
|
||||
|
||||
|
||||
scene.reset_shadows();
|
||||
scene.reset_environment();
|
||||
}
|
||||
|
|
|
@ -2,37 +2,37 @@
|
|||
|
||||
#include <cstdio>
|
||||
|
||||
#include "log.hpp"
|
||||
#include "assertions.hpp"
|
||||
#include "log.hpp"
|
||||
|
||||
prism::path prism::root_path(const path& path) {
|
||||
auto p = path;
|
||||
while(p.parent_path() != p && p.parent_path() != "/") {
|
||||
while (p.parent_path() != p && p.parent_path() != "/") {
|
||||
p = p.parent_path();
|
||||
}
|
||||
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
std::optional<prism::file> prism::open_file(const prism::path& path, const bool binary_mode) {
|
||||
Expects(!path.empty());
|
||||
|
||||
|
||||
auto str = get_file_path(path).string();
|
||||
FILE* file = fopen(str.c_str(), binary_mode ? "rb" : "r");
|
||||
if(file == nullptr) {
|
||||
if (file == nullptr) {
|
||||
prism::log("Failed to open file handle from {}!", str);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
return prism::file(file);
|
||||
}
|
||||
|
||||
prism::path prism::get_file_path(const prism::path& path) {
|
||||
auto fixed_path = path;
|
||||
auto root = root_path(path);
|
||||
if(root == game_domain) {
|
||||
if (root == game_domain) {
|
||||
fixed_path = domain_data[static_cast<int>(domain::game)] / path.lexically_relative(root_path(path));
|
||||
} else if(root == base_domain) {
|
||||
} else if (root == base_domain) {
|
||||
fixed_path = domain_data[static_cast<int>(domain::base)] / path.lexically_relative(root_path(path));
|
||||
}
|
||||
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
#include <imgui.h>
|
||||
#include <imgui_stdlib.h>
|
||||
|
||||
#include "engine.hpp"
|
||||
#include "platform.hpp"
|
||||
#include "assertions.hpp"
|
||||
#include "input.hpp"
|
||||
#include "app.hpp"
|
||||
#include "assertions.hpp"
|
||||
#include "engine.hpp"
|
||||
#include "input.hpp"
|
||||
#include "platform.hpp"
|
||||
|
||||
using prism::imgui_backend;
|
||||
|
||||
|
@ -32,12 +32,11 @@ const std::map<ImGuiKey, InputButton> imToPl = {
|
|||
{ImGuiKey_V, InputButton::V},
|
||||
{ImGuiKey_X, InputButton::X},
|
||||
{ImGuiKey_Y, InputButton::Y},
|
||||
{ImGuiKey_Z, InputButton::Z}
|
||||
};
|
||||
{ImGuiKey_Z, InputButton::Z}};
|
||||
|
||||
imgui_backend::imgui_backend() {
|
||||
ImGui::CreateContext();
|
||||
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.IniFilename = "";
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||
|
@ -47,16 +46,15 @@ imgui_backend::imgui_backend() {
|
|||
|
||||
for (auto& [im, pl] : imToPl)
|
||||
io.KeyMap[im] = platform::get_keycode(pl);
|
||||
|
||||
|
||||
const auto theme = platform::get_theme();
|
||||
switch(theme) {
|
||||
switch (theme) {
|
||||
case PlatformTheme::Light:
|
||||
ImGui::StyleColorsLight();
|
||||
break;
|
||||
case PlatformTheme::Dark:
|
||||
{
|
||||
case PlatformTheme::Dark: {
|
||||
ImGui::StyleColorsDark();
|
||||
|
||||
|
||||
auto& style = ImGui::GetStyle();
|
||||
style.FrameRounding = 3;
|
||||
style.FrameBorderSize = 0.0f;
|
||||
|
@ -74,48 +72,48 @@ imgui_backend::imgui_backend() {
|
|||
style.GrabRounding = 3.0f;
|
||||
style.TabRounding = 3.0f;
|
||||
style.WindowTitleAlign = ImVec2(0.0, 0.5);
|
||||
|
||||
|
||||
ImVec4* colors = ImGui::GetStyle().Colors;
|
||||
colors[ImGuiCol_FrameBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.54f);
|
||||
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.68f, 0.68f, 0.68f, 0.40f);
|
||||
colors[ImGuiCol_FrameBgActive] = ImVec4(0.42f, 0.47f, 0.52f, 0.67f);
|
||||
colors[ImGuiCol_TitleBgActive] = ImVec4(0.23f, 0.43f, 0.73f, 1.00f);
|
||||
colors[ImGuiCol_CheckMark] = ImVec4(0.74f, 0.80f, 0.87f, 1.00f);
|
||||
colors[ImGuiCol_SliderGrab] = ImVec4(0.46f, 0.54f, 0.64f, 1.00f);
|
||||
colors[ImGuiCol_Button] = ImVec4(0.38f, 0.51f, 0.65f, 0.40f);
|
||||
colors[ImGuiCol_ButtonHovered] = ImVec4(0.57f, 0.61f, 0.67f, 1.00f);
|
||||
colors[ImGuiCol_ButtonActive] = ImVec4(0.32f, 0.34f, 0.36f, 1.00f);
|
||||
colors[ImGuiCol_Tab] = ImVec4(0.22f, 0.27f, 0.33f, 0.86f);
|
||||
colors[ImGuiCol_TabActive] = ImVec4(0.33f, 0.51f, 0.75f, 1.00f);
|
||||
colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.30f, 0.33f, 0.38f, 1.00f);
|
||||
}
|
||||
break;
|
||||
colors[ImGuiCol_FrameBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.54f);
|
||||
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.68f, 0.68f, 0.68f, 0.40f);
|
||||
colors[ImGuiCol_FrameBgActive] = ImVec4(0.42f, 0.47f, 0.52f, 0.67f);
|
||||
colors[ImGuiCol_TitleBgActive] = ImVec4(0.23f, 0.43f, 0.73f, 1.00f);
|
||||
colors[ImGuiCol_CheckMark] = ImVec4(0.74f, 0.80f, 0.87f, 1.00f);
|
||||
colors[ImGuiCol_SliderGrab] = ImVec4(0.46f, 0.54f, 0.64f, 1.00f);
|
||||
colors[ImGuiCol_Button] = ImVec4(0.38f, 0.51f, 0.65f, 0.40f);
|
||||
colors[ImGuiCol_ButtonHovered] = ImVec4(0.57f, 0.61f, 0.67f, 1.00f);
|
||||
colors[ImGuiCol_ButtonActive] = ImVec4(0.32f, 0.34f, 0.36f, 1.00f);
|
||||
colors[ImGuiCol_Tab] = ImVec4(0.22f, 0.27f, 0.33f, 0.86f);
|
||||
colors[ImGuiCol_TabActive] = ImVec4(0.33f, 0.51f, 0.75f, 1.00f);
|
||||
colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.30f, 0.33f, 0.38f, 1.00f);
|
||||
} break;
|
||||
}
|
||||
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
|
||||
ImGuiPlatformMonitor monitor = {};
|
||||
|
||||
|
||||
const auto monitorArea = platform::get_monitor_resolution();
|
||||
monitor.MainPos = monitorArea.offset;
|
||||
monitor.MainSize = monitorArea.extent;
|
||||
|
||||
|
||||
const auto workArea = platform::get_monitor_work_area();
|
||||
monitor.WorkPos = workArea.offset;
|
||||
monitor.WorkSize = workArea.extent;
|
||||
|
||||
|
||||
monitor.DpiScale = platform::get_monitor_dpi();
|
||||
|
||||
platform_io.Monitors.push_back(monitor);
|
||||
|
||||
platform_io.Platform_CreateWindow = [](ImGuiViewport* viewport) {
|
||||
viewport->PlatformHandle = platform::open_window("", {viewport->Pos, viewport->Size}, WindowFlags::Borderless | WindowFlags::Hidden);
|
||||
viewport->PlatformHandle =
|
||||
platform::open_window("", {viewport->Pos, viewport->Size}, WindowFlags::Borderless | WindowFlags::Hidden);
|
||||
};
|
||||
|
||||
|
||||
platform_io.Platform_DestroyWindow = [](ImGuiViewport* viewport) {
|
||||
platform::close_window(viewport->PlatformHandle);
|
||||
};
|
||||
|
||||
|
||||
platform_io.Platform_ShowWindow = [](ImGuiViewport* viewport) {
|
||||
platform::show_window(viewport->PlatformHandle);
|
||||
};
|
||||
|
@ -123,32 +121,32 @@ imgui_backend::imgui_backend() {
|
|||
platform_io.Platform_SetWindowPos = [](ImGuiViewport* viewport, const ImVec2 pos) {
|
||||
platform::set_window_position(viewport->PlatformHandle, pos);
|
||||
};
|
||||
|
||||
|
||||
platform_io.Platform_GetWindowPos = [](ImGuiViewport* viewport) -> ImVec2 {
|
||||
return platform::get_window_position(viewport->PlatformHandle);
|
||||
};
|
||||
|
||||
|
||||
platform_io.Platform_SetWindowSize = [](ImGuiViewport* viewport, const ImVec2 size) {
|
||||
platform::set_window_size(viewport->PlatformHandle, size);
|
||||
::engine->resize(viewport->PlatformHandle, size);
|
||||
};
|
||||
|
||||
|
||||
platform_io.Platform_GetWindowSize = [](ImGuiViewport* viewport) -> ImVec2 {
|
||||
return platform::get_window_size(viewport->PlatformHandle);
|
||||
};
|
||||
|
||||
|
||||
platform_io.Platform_SetWindowFocus = [](ImGuiViewport* viewport) {
|
||||
platform::set_window_focused(viewport->PlatformHandle);
|
||||
};
|
||||
|
||||
|
||||
platform_io.Platform_GetWindowFocus = [](ImGuiViewport* viewport) {
|
||||
return platform::is_window_focused(viewport->PlatformHandle);
|
||||
};
|
||||
|
||||
|
||||
platform_io.Platform_GetWindowMinimized = [](ImGuiViewport*) {
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
platform_io.Platform_SetWindowTitle = [](ImGuiViewport* viewport, const char* title) {
|
||||
platform::set_window_title(viewport->PlatformHandle, title);
|
||||
};
|
||||
|
@ -156,13 +154,13 @@ imgui_backend::imgui_backend() {
|
|||
|
||||
void imgui_backend::process_move(platform::window_ptr identifier) {
|
||||
auto viewport = ImGui::FindViewportByPlatformHandle(identifier);
|
||||
if(viewport != nullptr)
|
||||
if (viewport != nullptr)
|
||||
viewport->PlatformRequestMove = true;
|
||||
}
|
||||
|
||||
void imgui_backend::process_resize(platform::window_ptr identifier) {
|
||||
auto viewport = ImGui::FindViewportByPlatformHandle(identifier);
|
||||
if(viewport != nullptr)
|
||||
if (viewport != nullptr)
|
||||
viewport->PlatformRequestResize = true;
|
||||
}
|
||||
|
||||
|
@ -172,8 +170,8 @@ void imgui_backend::begin_frame(const float delta_time) {
|
|||
const bool imgui_wants_text = io.WantTextInput;
|
||||
const bool input_is_text = ::engine->get_input()->is_text_input();
|
||||
|
||||
if(imgui_wants_text != input_is_text) {
|
||||
if(imgui_wants_text) {
|
||||
if (imgui_wants_text != input_is_text) {
|
||||
if (imgui_wants_text) {
|
||||
::engine->get_input()->begin_text_input();
|
||||
} else {
|
||||
::engine->get_input()->end_text_input();
|
||||
|
@ -184,26 +182,27 @@ void imgui_backend::begin_frame(const float delta_time) {
|
|||
const auto drawableSize = platform::get_window_drawable_size(::engine->get_main_window());
|
||||
|
||||
io.DisplaySize = size;
|
||||
io.DisplayFramebufferScale = ImVec2(static_cast<float>(drawableSize.width) / static_cast<float>(size.width),
|
||||
static_cast<float>(drawableSize.height) / static_cast<float>(size.height));
|
||||
io.DisplayFramebufferScale = ImVec2(
|
||||
static_cast<float>(drawableSize.width) / static_cast<float>(size.width),
|
||||
static_cast<float>(drawableSize.height) / static_cast<float>(size.height));
|
||||
io.DeltaTime = delta_time;
|
||||
io.KeyCtrl = platform::get_key_down(InputButton::Ctrl);
|
||||
io.KeyShift = platform::get_key_down(InputButton::Shift);
|
||||
io.KeyAlt = platform::get_key_down(InputButton::Alt);
|
||||
io.KeySuper = platform::get_key_down(InputButton::Super);
|
||||
io.MouseHoveredViewport = 0;
|
||||
|
||||
|
||||
const auto [sx, sy] = platform::get_wheel_delta();
|
||||
io.MouseWheel = sy;
|
||||
io.MouseWheelH = sx;
|
||||
|
||||
if(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) {
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) {
|
||||
const auto [x, y] = platform::get_screen_cursor_position();
|
||||
|
||||
|
||||
io.MousePos = ImVec2(static_cast<float>(x), static_cast<float>(y));
|
||||
} else {
|
||||
const auto [x, y] = platform::get_cursor_position();
|
||||
|
||||
|
||||
io.MousePos = ImVec2(static_cast<float>(x), static_cast<float>(y));
|
||||
}
|
||||
|
||||
|
@ -214,28 +213,31 @@ void imgui_backend::begin_frame(const float delta_time) {
|
|||
|
||||
ImGui::NewFrame();
|
||||
|
||||
if(open_dialog_next_frame) {
|
||||
if (open_dialog_next_frame) {
|
||||
ImGui::OpenPopup("Open File");
|
||||
open_dialog_next_frame = false;
|
||||
}
|
||||
|
||||
if(save_dialog_next_frame) {
|
||||
if (save_dialog_next_frame) {
|
||||
ImGui::OpenPopup("Save File");
|
||||
save_dialog_next_frame = false;
|
||||
}
|
||||
|
||||
const auto dialog_function = [](dialog_data& data) {
|
||||
if(ImGui::Selectable("..", false, ImGuiSelectableFlags_DontClosePopups))
|
||||
if (ImGui::Selectable("..", false, ImGuiSelectableFlags_DontClosePopups))
|
||||
data.current_path = data.current_path.parent_path();
|
||||
|
||||
if(data.select_directory) {
|
||||
if(ImGui::Selectable(".", false, ImGuiSelectableFlags_DontClosePopups))
|
||||
if (data.select_directory) {
|
||||
if (ImGui::Selectable(".", false, ImGuiSelectableFlags_DontClosePopups))
|
||||
data.selected_path = data.current_path;
|
||||
}
|
||||
|
||||
for(const auto& dir_ent : std::filesystem::directory_iterator(data.current_path)) {
|
||||
if(ImGui::Selectable(dir_ent.path().string().c_str(), data.selected_path == dir_ent.path(), ImGuiSelectableFlags_DontClosePopups)) {
|
||||
if(dir_ent.is_directory())
|
||||
for (const auto& dir_ent : std::filesystem::directory_iterator(data.current_path)) {
|
||||
if (ImGui::Selectable(
|
||||
dir_ent.path().string().c_str(),
|
||||
data.selected_path == dir_ent.path(),
|
||||
ImGuiSelectableFlags_DontClosePopups)) {
|
||||
if (dir_ent.is_directory())
|
||||
data.current_path = dir_ent.path();
|
||||
else
|
||||
data.selected_path = dir_ent.path();
|
||||
|
@ -244,21 +246,21 @@ void imgui_backend::begin_frame(const float delta_time) {
|
|||
|
||||
ImGui::TextDisabled("Selected: %s", data.selected_path.c_str());
|
||||
|
||||
if(ImGui::Button("OK")) {
|
||||
if (ImGui::Button("OK")) {
|
||||
data.return_function(data.selected_path.string());
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
if(ImGui::Button("Cancel"))
|
||||
if (ImGui::Button("Cancel"))
|
||||
ImGui::CloseCurrentPopup();
|
||||
};
|
||||
|
||||
if(ImGui::BeginPopup("Open File")) {
|
||||
if (ImGui::BeginPopup("Open File")) {
|
||||
dialog_function(open_dialog_data);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
if(ImGui::BeginPopup("Save File")) {
|
||||
if (ImGui::BeginPopup("Save File")) {
|
||||
dialog_function(save_dialog_data);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
@ -281,7 +283,7 @@ void imgui_backend::process_key_up(unsigned int key_code) {
|
|||
Expects(key_code >= 0);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
|
||||
io.KeysDown[key_code] = false;
|
||||
}
|
||||
|
||||
|
@ -294,7 +296,10 @@ void prism::imgui_backend::process_text_input(const std::string_view string) {
|
|||
io.AddInputCharactersUTF8(string.data());
|
||||
}
|
||||
|
||||
void prism::imgui_backend::open_dialog(const bool, std::function<void(std::string)> returnFunction, bool openDirectory) {
|
||||
void prism::imgui_backend::open_dialog(
|
||||
const bool,
|
||||
std::function<void(std::string)> returnFunction,
|
||||
bool openDirectory) {
|
||||
open_dialog_next_frame = true;
|
||||
open_dialog_data.current_path = std::filesystem::current_path();
|
||||
open_dialog_data.return_function = returnFunction;
|
||||
|
|
|
@ -17,8 +17,7 @@ void input_system::update() {
|
|||
const auto& [x, y] = platform::get_cursor_position();
|
||||
auto& [oldX, oldY] = _last_cursor_position;
|
||||
|
||||
const auto [width, height] =
|
||||
platform::get_window_size(::engine->get_main_window());
|
||||
const auto [width, height] = platform::get_window_size(::engine->get_main_window());
|
||||
|
||||
float xDelta = (x - oldX) / (float)width;
|
||||
float yDelta = (y - oldY) / (float)height;
|
||||
|
@ -36,15 +35,15 @@ void input_system::update() {
|
|||
for (auto& [key, value] : binding.buttons) {
|
||||
bool is_pressed = false;
|
||||
switch (key) {
|
||||
case InputButton::MouseLeft:
|
||||
is_pressed = platform::get_mouse_button_down(0);
|
||||
break;
|
||||
case InputButton::MouseRight:
|
||||
is_pressed = platform::get_mouse_button_down(1);
|
||||
break;
|
||||
default:
|
||||
is_pressed = platform::get_key_down(key);
|
||||
break;
|
||||
case InputButton::MouseLeft:
|
||||
is_pressed = platform::get_mouse_button_down(0);
|
||||
break;
|
||||
case InputButton::MouseRight:
|
||||
is_pressed = platform::get_mouse_button_down(1);
|
||||
break;
|
||||
default:
|
||||
is_pressed = platform::get_key_down(key);
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_pressed) {
|
||||
|
@ -73,30 +72,30 @@ void input_system::update() {
|
|||
float nextValue = 0.0f;
|
||||
|
||||
switch (axis) {
|
||||
case axis::MouseX:
|
||||
nextValue = xDelta;
|
||||
break;
|
||||
case axis::MouseY:
|
||||
nextValue = yDelta;
|
||||
break;
|
||||
case axis::ScrollX:
|
||||
nextValue = sx;
|
||||
break;
|
||||
case axis::ScrollY:
|
||||
nextValue = sy;
|
||||
break;
|
||||
case axis::LeftStickX:
|
||||
nextValue = lx;
|
||||
break;
|
||||
case axis::LeftStickY:
|
||||
nextValue = ly;
|
||||
break;
|
||||
case axis::RightStickX:
|
||||
nextValue = rx;
|
||||
break;
|
||||
case axis::RightStickY:
|
||||
nextValue = ry;
|
||||
break;
|
||||
case axis::MouseX:
|
||||
nextValue = xDelta;
|
||||
break;
|
||||
case axis::MouseY:
|
||||
nextValue = yDelta;
|
||||
break;
|
||||
case axis::ScrollX:
|
||||
nextValue = sx;
|
||||
break;
|
||||
case axis::ScrollY:
|
||||
nextValue = sy;
|
||||
break;
|
||||
case axis::LeftStickX:
|
||||
nextValue = lx;
|
||||
break;
|
||||
case axis::LeftStickY:
|
||||
nextValue = ly;
|
||||
break;
|
||||
case axis::RightStickX:
|
||||
nextValue = rx;
|
||||
break;
|
||||
case axis::RightStickY:
|
||||
nextValue = ry;
|
||||
break;
|
||||
}
|
||||
|
||||
if (nextValue != 0.0f)
|
||||
|
@ -112,8 +111,7 @@ void input_system::add_binding(const std::string& name) {
|
|||
_input_bindings.push_back(data);
|
||||
}
|
||||
|
||||
void input_system::add_binding_button(const std::string& name, InputButton key,
|
||||
float value) {
|
||||
void input_system::add_binding_button(const std::string& name, InputButton key, float value) {
|
||||
for (auto& binding : _input_bindings) {
|
||||
if (binding.name == name)
|
||||
binding.buttons[key] = value;
|
||||
|
@ -166,7 +164,9 @@ void input_system::end_text_input() {
|
|||
platform::end_text_input();
|
||||
}
|
||||
|
||||
bool input_system::is_text_input() const { return _in_text_input; }
|
||||
bool input_system::is_text_input() const {
|
||||
return _in_text_input;
|
||||
}
|
||||
|
||||
bool input_system::get_allowable_text_button(unsigned int keycode) const {
|
||||
if (platform::get_keycode(InputButton::Backspace) == keycode)
|
||||
|
|
|
@ -12,27 +12,29 @@ Physics::Physics() {
|
|||
Physics::~Physics() {}
|
||||
|
||||
void Physics::update(float deltaTime) {
|
||||
if(engine->get_scene() == nullptr)
|
||||
if (engine->get_scene() == nullptr)
|
||||
return;
|
||||
|
||||
for(auto [obj, rigidbody] : engine->get_scene()->get_all<Rigidbody>()) {
|
||||
if(rigidbody.body != nullptr) {
|
||||
if(rigidbody.type == Rigidbody::Type::Dynamic) {
|
||||
if(rigidbody.stored_force != prism::float3(0.0f)) {
|
||||
rigidbody.body->setLinearVelocity(btVector3(rigidbody.stored_force.x, rigidbody.stored_force.y, rigidbody.stored_force.z));
|
||||
|
||||
for (auto [obj, rigidbody] : engine->get_scene()->get_all<Rigidbody>()) {
|
||||
if (rigidbody.body != nullptr) {
|
||||
if (rigidbody.type == Rigidbody::Type::Dynamic) {
|
||||
if (rigidbody.stored_force != prism::float3(0.0f)) {
|
||||
rigidbody.body->setLinearVelocity(
|
||||
btVector3(rigidbody.stored_force.x, rigidbody.stored_force.y, rigidbody.stored_force.z));
|
||||
rigidbody.stored_force = prism::float3(0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
world->stepSimulation(deltaTime);
|
||||
|
||||
for(auto [object, collision] : engine->get_scene()->get_all<Collision>()) {
|
||||
if(collision.shape == nullptr && !collision.is_trigger) {
|
||||
switch(collision.type) {
|
||||
|
||||
for (auto [object, collision] : engine->get_scene()->get_all<Collision>()) {
|
||||
if (collision.shape == nullptr && !collision.is_trigger) {
|
||||
switch (collision.type) {
|
||||
case Collision::Type::Cube:
|
||||
collision.shape = new btBoxShape(btVector3(collision.size.x / 2.0f, collision.size.y / 2.0f, collision.size.z / 2.0f));
|
||||
collision.shape = new btBoxShape(
|
||||
btVector3(collision.size.x / 2.0f, collision.size.y / 2.0f, collision.size.z / 2.0f));
|
||||
break;
|
||||
case Collision::Type::Capsule:
|
||||
collision.shape = new btCapsuleShape(0.5f, collision.size.y);
|
||||
|
@ -40,43 +42,45 @@ void Physics::update(float deltaTime) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(auto [obj, rigidbody] : engine->get_scene()->get_all<Rigidbody>()) {
|
||||
|
||||
for (auto [obj, rigidbody] : engine->get_scene()->get_all<Rigidbody>()) {
|
||||
auto& transform = engine->get_scene()->get<Transform>(obj);
|
||||
|
||||
if(rigidbody.body == nullptr) {
|
||||
|
||||
if (rigidbody.body == nullptr) {
|
||||
btTransform t;
|
||||
t.setIdentity();
|
||||
|
||||
|
||||
t.setOrigin(btVector3(transform.position.x, transform.position.y, transform.position.z));
|
||||
t.setRotation(btQuaternion(transform.rotation.x, transform.rotation.y, transform.rotation.z, transform.rotation.w));
|
||||
t.setRotation(
|
||||
btQuaternion(transform.rotation.x, transform.rotation.y, transform.rotation.z, transform.rotation.w));
|
||||
|
||||
btDefaultMotionState* motionState = new btDefaultMotionState(t);
|
||||
|
||||
btScalar bodyMass = rigidbody.mass;
|
||||
btVector3 bodyInertia;
|
||||
|
||||
if(rigidbody.mass != 0)
|
||||
engine->get_scene()->get<Collision>(obj).shape->calculateLocalInertia(bodyMass, bodyInertia);
|
||||
|
||||
btRigidBody::btRigidBodyConstructionInfo bodyCI = btRigidBody::btRigidBodyConstructionInfo(bodyMass, motionState, engine->get_scene()->get<Collision>(obj).shape, bodyInertia);
|
||||
|
||||
if (rigidbody.mass != 0)
|
||||
engine->get_scene()->get<Collision>(obj).shape->calculateLocalInertia(bodyMass, bodyInertia);
|
||||
|
||||
btRigidBody::btRigidBodyConstructionInfo bodyCI = btRigidBody::btRigidBodyConstructionInfo(
|
||||
bodyMass, motionState, engine->get_scene()->get<Collision>(obj).shape, bodyInertia);
|
||||
|
||||
bodyCI.m_friction = rigidbody.friction;
|
||||
|
||||
rigidbody.body = new btRigidBody(bodyCI);
|
||||
|
||||
if(!rigidbody.enable_deactivation)
|
||||
|
||||
if (!rigidbody.enable_deactivation)
|
||||
rigidbody.body->setActivationState(DISABLE_DEACTIVATION);
|
||||
|
||||
if(!rigidbody.enable_rotation)
|
||||
|
||||
if (!rigidbody.enable_rotation)
|
||||
rigidbody.body->setAngularFactor(btVector3(0, 0, 0));
|
||||
|
||||
|
||||
world->addRigidBody(rigidbody.body);
|
||||
|
||||
|
||||
rigidbody.body->setUserIndex(obj);
|
||||
}
|
||||
|
||||
if(rigidbody.type == Rigidbody::Type::Dynamic) {
|
||||
|
||||
if (rigidbody.type == Rigidbody::Type::Dynamic) {
|
||||
btTransform trans = rigidbody.body->getWorldTransform();
|
||||
transform.position = prism::float3(trans.getOrigin().x(), trans.getOrigin().y(), trans.getOrigin().z());
|
||||
} else {
|
||||
|
@ -84,7 +88,8 @@ void Physics::update(float deltaTime) {
|
|||
t.setIdentity();
|
||||
|
||||
t.setOrigin(btVector3(transform.position.x, transform.position.y, transform.position.z));
|
||||
t.setRotation(btQuaternion(transform.rotation.x, transform.rotation.y, transform.rotation.z, transform.rotation.w));
|
||||
t.setRotation(
|
||||
btQuaternion(transform.rotation.x, transform.rotation.y, transform.rotation.z, transform.rotation.w));
|
||||
|
||||
rigidbody.body->setWorldTransform(t);
|
||||
}
|
||||
|
@ -92,11 +97,11 @@ void Physics::update(float deltaTime) {
|
|||
}
|
||||
|
||||
void Physics::remove_object(prism::Object object) {
|
||||
if(engine->get_scene()->has<Rigidbody>(object)) {
|
||||
for(int i = 0 ; i < world->getNumCollisionObjects(); i++) {
|
||||
if (engine->get_scene()->has<Rigidbody>(object)) {
|
||||
for (int i = 0; i < world->getNumCollisionObjects(); i++) {
|
||||
auto obj = world->getCollisionObjectArray()[i];
|
||||
|
||||
if(obj->getUserIndex() == object) {
|
||||
|
||||
if (obj->getUserIndex() == object) {
|
||||
world->removeCollisionObject(obj);
|
||||
delete obj;
|
||||
}
|
||||
|
@ -106,41 +111,41 @@ void Physics::remove_object(prism::Object object) {
|
|||
|
||||
Physics::RayResult Physics::raycast(prism::float3 from, prism::float3 to) {
|
||||
Physics::RayResult result;
|
||||
|
||||
|
||||
btVector3 btFrom(from.x, from.y, from.z);
|
||||
btVector3 btTo(to.x, to.y, to.z);
|
||||
|
||||
|
||||
btCollisionWorld::AllHitsRayResultCallback res(btFrom, btTo);
|
||||
|
||||
world->rayTest(btFrom, btTo, res);
|
||||
|
||||
int closestCollisionObject = prism::NullObject;
|
||||
float closestHitFraction = 1000.0f;
|
||||
|
||||
for(int i = 0; i < res.m_collisionObjects.size(); i++) {
|
||||
if(!engine->get_scene()->get<Collision>(res.m_collisionObjects[i]->getUserIndex()).exclude_from_raycast) {
|
||||
if(res.m_hitFractions[i] < closestHitFraction) {
|
||||
|
||||
for (int i = 0; i < res.m_collisionObjects.size(); i++) {
|
||||
if (!engine->get_scene()->get<Collision>(res.m_collisionObjects[i]->getUserIndex()).exclude_from_raycast) {
|
||||
if (res.m_hitFractions[i] < closestHitFraction) {
|
||||
closestCollisionObject = i;
|
||||
closestHitFraction = res.m_hitFractions[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(closestCollisionObject != prism::NullObject) {
|
||||
if (closestCollisionObject != prism::NullObject) {
|
||||
result.hasHit = true;
|
||||
|
||||
|
||||
auto vec = res.m_hitPointWorld[closestCollisionObject];
|
||||
|
||||
|
||||
result.location = prism::float3(vec.x(), vec.y(), vec.z());
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Physics::reset() {
|
||||
if(world != nullptr)
|
||||
if (world != nullptr)
|
||||
world.reset();
|
||||
|
||||
|
||||
broadphase = std::make_unique<btDbvtBroadphase>();
|
||||
|
||||
collisionConfiguration = std::make_unique<btDefaultCollisionConfiguration>();
|
||||
|
@ -148,6 +153,7 @@ void Physics::reset() {
|
|||
|
||||
solver = std::make_unique<btSequentialImpulseConstraintSolver>();
|
||||
|
||||
world = std::make_unique<btDiscreteDynamicsWorld>(dispatcher.get(), broadphase.get(), solver.get(), collisionConfiguration.get());
|
||||
world = std::make_unique<btDiscreteDynamicsWorld>(
|
||||
dispatcher.get(), broadphase.get(), solver.get(), collisionConfiguration.get());
|
||||
world->setGravity(btVector3(0.0f, -9.8f, 0.0f));
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#include "scene.hpp"
|
||||
|
||||
#include "json_conversions.hpp"
|
||||
#include "file.hpp"
|
||||
#include "engine.hpp"
|
||||
#include "transform.hpp"
|
||||
#include "asset.hpp"
|
||||
#include "engine.hpp"
|
||||
#include "file.hpp"
|
||||
#include "json_conversions.hpp"
|
||||
#include "transform.hpp"
|
||||
|
||||
void camera_look_at(Scene& scene, prism::Object cam, prism::float3 pos, prism::float3 target) {
|
||||
scene.get<Transform>(cam).position = pos;
|
||||
|
@ -18,15 +18,15 @@ void load_transform_component(nlohmann::json j, Transform& t) {
|
|||
}
|
||||
|
||||
void load_renderable_component(nlohmann::json j, Renderable& t) {
|
||||
if(j.contains("path"))
|
||||
if (j.contains("path"))
|
||||
t.mesh = assetm->get<Mesh>(prism::game_domain / j["path"].get<std::string_view>());
|
||||
|
||||
for(auto& material : j["materials"])
|
||||
|
||||
for (auto& material : j["materials"])
|
||||
t.materials.push_back(assetm->get<Material>(prism::game_domain / material.get<std::string_view>()));
|
||||
}
|
||||
|
||||
void load_camera_component(nlohmann::json j, Camera& camera) {
|
||||
if(j.contains("fov"))
|
||||
if (j.contains("fov"))
|
||||
camera.fov = j["fov"];
|
||||
}
|
||||
|
||||
|
@ -34,15 +34,15 @@ void load_light_component(nlohmann::json j, Light& light) {
|
|||
light.color = j["color"];
|
||||
light.power = j["power"];
|
||||
light.type = j["type"];
|
||||
|
||||
if(j.count("size") && !j.count("spot_size"))
|
||||
|
||||
if (j.count("size") && !j.count("spot_size"))
|
||||
light.size = j["size"];
|
||||
else if(j.count("spot_size")) {
|
||||
else if (j.count("spot_size")) {
|
||||
light.size = j["size"];
|
||||
light.spot_size = j["spot_size"];
|
||||
}
|
||||
|
||||
if(j.count("enable_shadows")) {
|
||||
|
||||
if (j.count("enable_shadows")) {
|
||||
light.enable_shadows = j["enable_shadows"];
|
||||
light.use_dynamic_shadows = j["use_dynamic_shadows"];
|
||||
}
|
||||
|
@ -52,10 +52,10 @@ void load_collision_component(nlohmann::json j, Collision& collision) {
|
|||
collision.type = j["type"];
|
||||
collision.size = j["size"];
|
||||
|
||||
if(j.contains("is_trigger")) {
|
||||
if (j.contains("is_trigger")) {
|
||||
collision.is_trigger = j["is_trigger"];
|
||||
|
||||
if(collision.is_trigger)
|
||||
if (collision.is_trigger)
|
||||
collision.trigger_id = j["trigger_id"];
|
||||
}
|
||||
}
|
||||
|
@ -66,13 +66,13 @@ void load_rigidbody_component(nlohmann::json j, Rigidbody& rigidbody) {
|
|||
}
|
||||
|
||||
void load_probe_component(nlohmann::json j, EnvironmentProbe& probe) {
|
||||
if(j.contains("size"))
|
||||
if (j.contains("size"))
|
||||
probe.size = j["size"];
|
||||
|
||||
if(j.contains("is_sized"))
|
||||
|
||||
if (j.contains("is_sized"))
|
||||
probe.is_sized = j["is_sized"];
|
||||
|
||||
if(j.contains("intensity"))
|
||||
|
||||
if (j.contains("intensity"))
|
||||
probe.intensity = j["intensity"];
|
||||
}
|
||||
|
||||
|
@ -84,24 +84,24 @@ prism::Object load_object(Scene& scene, const nlohmann::json& obj) {
|
|||
|
||||
load_transform_component(obj["transform"], scene.get<Transform>(o));
|
||||
|
||||
if(obj.contains("renderable"))
|
||||
if (obj.contains("renderable"))
|
||||
load_renderable_component(obj["renderable"], scene.add<Renderable>(o));
|
||||
|
||||
if(obj.contains("light"))
|
||||
if (obj.contains("light"))
|
||||
load_light_component(obj["light"], scene.add<Light>(o));
|
||||
|
||||
if(obj.contains("camera"))
|
||||
if (obj.contains("camera"))
|
||||
load_camera_component(obj["camera"], scene.add<Camera>(o));
|
||||
|
||||
if(obj.contains("collision"))
|
||||
if (obj.contains("collision"))
|
||||
load_collision_component(obj["collision"], scene.add<Collision>(o));
|
||||
|
||||
if(obj.contains("rigidbody"))
|
||||
if (obj.contains("rigidbody"))
|
||||
load_rigidbody_component(obj["rigidbody"], scene.add<Rigidbody>(o));
|
||||
|
||||
if(obj.contains("environment_probe"))
|
||||
if (obj.contains("environment_probe"))
|
||||
load_probe_component(obj["environment_probe"], scene.add<EnvironmentProbe>(o));
|
||||
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
|
@ -111,12 +111,12 @@ void save_transform_component(nlohmann::json& j, const Transform& t) {
|
|||
j["rotation"] = t.rotation;
|
||||
}
|
||||
|
||||
void save_renderable_component(nlohmann::json& j, const Renderable &mesh) {
|
||||
if(mesh.mesh)
|
||||
void save_renderable_component(nlohmann::json& j, const Renderable& mesh) {
|
||||
if (mesh.mesh)
|
||||
j["path"] = mesh.mesh->path;
|
||||
|
||||
for(auto& material : mesh.materials) {
|
||||
if(material)
|
||||
|
||||
for (auto& material : mesh.materials) {
|
||||
if (material)
|
||||
j["materials"].push_back(material->path);
|
||||
}
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ void save_collision_component(nlohmann::json& j, const Collision& collision) {
|
|||
j["size"] = collision.size;
|
||||
|
||||
j["is_trigger"] = collision.is_trigger;
|
||||
if(collision.is_trigger)
|
||||
if (collision.is_trigger)
|
||||
j["trigger_id"] = collision.trigger_id;
|
||||
}
|
||||
|
||||
|
@ -162,30 +162,30 @@ nlohmann::json save_object(prism::Object obj) {
|
|||
|
||||
j["name"] = data.name;
|
||||
|
||||
if(data.parent != prism::NullObject)
|
||||
if (data.parent != prism::NullObject)
|
||||
j["parent"] = engine->get_scene()->get(data.parent).name;
|
||||
|
||||
save_transform_component(j["transform"], engine->get_scene()->get<Transform>(obj));
|
||||
|
||||
auto scene = engine->get_scene();
|
||||
|
||||
if(scene->has<Renderable>(obj))
|
||||
if (scene->has<Renderable>(obj))
|
||||
save_renderable_component(j["renderable"], scene->get<Renderable>(obj));
|
||||
|
||||
if(scene->has<Light>(obj))
|
||||
if (scene->has<Light>(obj))
|
||||
save_light_component(j["light"], scene->get<Light>(obj));
|
||||
|
||||
if(scene->has<Camera>(obj))
|
||||
if (scene->has<Camera>(obj))
|
||||
save_camera_component(j["camera"], scene->get<Camera>(obj));
|
||||
|
||||
if(scene->has<Collision>(obj))
|
||||
if (scene->has<Collision>(obj))
|
||||
save_collision_component(j["collision"], scene->get<Collision>(obj));
|
||||
|
||||
if(scene->has<Rigidbody>(obj))
|
||||
if (scene->has<Rigidbody>(obj))
|
||||
save_rigidbody_component(j["rigidbody"], scene->get<Rigidbody>(obj));
|
||||
|
||||
if(scene->has<EnvironmentProbe>(obj))
|
||||
if (scene->has<EnvironmentProbe>(obj))
|
||||
save_probe_component(j["environment_probe"], scene->get<EnvironmentProbe>(obj));
|
||||
|
||||
|
||||
return j;
|
||||
}
|
||||
|
|
Reference in a new issue