Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,4 @@ compile_commands.json

.DS_Store
Oxylus.xcodeproj
vsxmake2026
7 changes: 3 additions & 4 deletions Oxylus/include/Core/App.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ class App {
auto with_assets_directory(this App& self, const std::filesystem::path& dir) -> App&;

template <typename F>
void defer_to_next_frame(this App& self, F&& func) {
static void defer_to_next_frame(F&& func) {
std::function<void()> task = std::forward<F>(func);

auto lock = std::unique_lock(self.mutex);
self.pending_tasks.push_back(std::move(task));
auto lock = std::unique_lock(get()->mutex);
get()->pending_tasks.push_back(std::move(task));
}

template <typename T, typename... Args>
Expand Down Expand Up @@ -104,7 +104,6 @@ class App {
Timestep timestep = {};

bool is_running = true;
float last_frame_time = 0.0f;

auto run_deferred_tasks(this App& self) -> void;
};
Expand Down
19 changes: 6 additions & 13 deletions Oxylus/include/Physics/Physics.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#include "Render/DebugRenderer.hpp"

#include <Jolt/Core/JobSystemThreadPool.h>
#include <Jolt/Physics/Collision/CollisionCollectorImpl.h>
#include <Jolt/Physics/PhysicsSystem.h>
// clang-format on

Expand All @@ -27,21 +26,15 @@ class Physics {

auto init() -> std::expected<void, std::string>;
auto deinit() -> std::expected<void, std::string>;
void step(float physicsTs);
void debug_draw();

JPH::PhysicsSystem* get_physics_system() { return physics_system; };
JPH::BodyInterface& get_body_interface() { return physics_system->GetBodyInterface(); }
const JPH::BroadPhaseQuery& get_broad_phase_query() { return physics_system->GetBroadPhaseQuery(); }
const JPH::BodyLockInterface& get_body_interface_lock() { return physics_system->GetBodyLockInterface(); }
PhysicsDebugRenderer* get_debug_renderer() { return debug_renderer; }
auto new_system() const -> std::unique_ptr<JPH::PhysicsSystem>;
auto new_debug_renderer() const -> std::unique_ptr<PhysicsDebugRenderer>;

JPH::AllHitCollisionCollector<JPH::RayCastBodyCollector> cast_ray(const RayCast& ray_cast);
auto get_temp_allocator() const -> JPH::TempAllocatorImpl* { return temp_allocator.get(); }
auto get_job_system() const -> JPH::JobSystemThreadPool* { return job_system.get(); }

private:
JPH::PhysicsSystem* physics_system = nullptr;
JPH::TempAllocatorImpl* temp_allocator = nullptr;
JPH::JobSystemThreadPool* job_system = nullptr;
PhysicsDebugRenderer* debug_renderer = nullptr;
std::unique_ptr<JPH::TempAllocatorImpl> temp_allocator = nullptr;
std::unique_ptr<JPH::JobSystemThreadPool> job_system = nullptr;
};
} // namespace ox
5 changes: 5 additions & 0 deletions Oxylus/include/Render/Renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ class Renderer {
auto init(this Renderer& self) -> std::expected<void, std::string>;
auto deinit(this Renderer& self) -> std::expected<void, std::string>;

auto new_frame(this Renderer& self) -> void;

auto new_instance(Scene& scene) -> std::unique_ptr<RendererInstance>;

private:
Expand All @@ -156,7 +158,10 @@ class Renderer {
bool initalized = false;

Texture sky_transmittance_lut_view;
vuk::Value<vuk::ImageAttachment> acquired_sky_transmittance_lut_view;
Texture sky_multiscatter_lut_view;
vuk::Value<vuk::ImageAttachment> acquired_sky_multiscatter_lut_view;
Texture hilbert_noise_lut;
vuk::Value<vuk::ImageAttachment> acquired_hilbert_noise_lut;
};
} // namespace ox
2 changes: 2 additions & 0 deletions Oxylus/include/Render/RendererInstance.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,8 @@ class RendererInstance {
auto update_vbgtao_info(this RendererInstance&) -> void;

private:
bool update_ran_this_frame = false; // Sanity Check

SharedResources shared_resources = {};
std::vector<RenderStageCallback> stage_callbacks;
std::vector<std::vector<usize>> before_callbacks;
Expand Down
4 changes: 2 additions & 2 deletions Oxylus/include/Render/Utils/DDS.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,8 +363,8 @@ DDS_NO_DISCARD inline ReadResult readImage(std::uint8_t* ptr, std::size_t fileSi
}

// Determine format information
auto getFormatInfo = [](const dds::FileHeader* header) -> DXGI_FORMAT {
auto& pf = header->pixelFormat;
auto getFormatInfo = [](const dds::FileHeader* h) -> DXGI_FORMAT {
auto& pf = h->pixelFormat;
if (hasBit(pf.flags, PixelFormatFlags::FourCC)) {
switch (pf.fourCC) {
// clang-format off
Expand Down
42 changes: 26 additions & 16 deletions Oxylus/include/Scene/Scene.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,20 @@
#include <Jolt/Core/Core.h>
#include <Jolt/Physics/Body/Body.h>
#include <Jolt/Physics/Collision/ContactListener.h>
#include <Jolt/Physics/Collision/CollisionCollectorImpl.h>
#include <Jolt/Physics/PhysicsSystem.h>
// clang-format on

#include <simdjson.h>

#include "Core/UUID.hpp"
#include "Physics/PhysicsInterfaces.hpp"
#include "Render/DebugRenderer.hpp"
#include "Render/RendererInstance.hpp"
#include "Scene/ECSModule/Core.hpp"
#include "Scene/SceneGPU.hpp"
#include "Scripting/LuaSystem.hpp"
#include "Utils/Timestep.hpp"
// clang-format on

template <>
struct ankerl::unordered_dense::hash<flecs::id> {
Expand All @@ -33,8 +38,6 @@ struct ankerl::unordered_dense::hash<flecs::entity> {

namespace ox {
struct JsonWriter;
class Physics3DContactListener;
class Physics3DBodyActivationListener;

struct ComponentDB {
std::vector<flecs::id> components = {};
Expand All @@ -53,7 +56,7 @@ class Scene {
flecs::world world;
ComponentDB component_db = {};

f32 physics_interval = 1.f / 60.f; // used only on initalization
f32 physics_interval = 1.f / 60.f; // used only on initialization

std::vector<GPU::TransformID> dirty_transforms = {};
SlotMap<GPU::Transforms, GPU::TransformID> transforms = {};
Expand All @@ -64,6 +67,7 @@ class Scene {
std::vector<GPU::Material> gpu_materials = {};

bool meshes_dirty = false;
bool force_material_update = true;
u32 mesh_instance_count = 0;
u32 max_meshlet_instance_count = 0;

Expand Down Expand Up @@ -114,7 +118,10 @@ class Scene {
auto add_lua_system(this Scene& self, const UUID& lua_script) -> void;
auto remove_lua_system(this Scene& self, const UUID& lua_script) -> void;

// Physics interfaces
// Physics
auto get_physics_system(this const Scene& self) -> JPH::PhysicsSystem*;
auto cast_ray(this const Scene& self, const RayCast& ray_cast)
-> JPH::AllHitCollisionCollector<JPH::RayCastBodyCollector>;
auto on_contact_added(
const JPH::Body& body1,
const JPH::Body& body2,
Expand All @@ -132,13 +139,14 @@ class Scene {
auto on_body_activated(const JPH::BodyID& body_id, JPH::uint64 body_user_data) -> void;
auto on_body_deactivated(const JPH::BodyID& body_id, JPH::uint64 body_user_data) -> void;

auto create_rigidbody(flecs::entity entity, const TransformComponent& transform, RigidBodyComponent& component)
-> void;
auto create_rigidbody(
this Scene& self, flecs::entity entity, const TransformComponent& transform, RigidBodyComponent& component
) -> void;
auto create_character_controller(
flecs::entity entity, const TransformComponent& transform, CharacterControllerComponent& component
) const -> void;

auto get_renderer_instance() -> RendererInstance* { return renderer_instance.get(); }
auto get_renderer_instance() const -> RendererInstance* { return renderer_instance.get(); }

// This will reset RendererInstance's reference to acquired vuk resources.
// If I don't do this vuk complains about resources not being unique when there is another RendererInstance being
Expand All @@ -163,13 +171,7 @@ class Scene {
private:
bool running = false;

std::shared_mutex physics_mutex = {};

auto add_transform(this Scene& self, flecs::entity entity) -> GPU::TransformID;
auto remove_transform(this Scene& self, flecs::entity entity) -> void;

std::vector<std::function<void(Scene* scene)>> deferred_functions_ = {};
auto run_deferred_functions(this Scene& self) -> void;

// Lua
ankerl::unordered_dense::map<UUID, LuaSystem*> lua_systems = {};
Expand All @@ -178,7 +180,15 @@ class Scene {
std::unique_ptr<RendererInstance> renderer_instance = nullptr;

// Physics
std::unique_ptr<Physics3DContactListener> contact_listener_3d;
std::unique_ptr<Physics3DBodyActivationListener> body_activation_listener_3d;
std::shared_mutex physics_mutex = {};
std::unique_ptr<JPH::PhysicsSystem> physics_system = nullptr;
std::unique_ptr<PhysicsDebugRenderer> physics_debug_renderer = nullptr;
std::unique_ptr<Physics3DContactListener> contact_listener_3d = nullptr;
std::unique_ptr<Physics3DBodyActivationListener> body_activation_listener_3d = nullptr;

auto add_transform(this Scene& self, flecs::entity entity) -> GPU::TransformID;
auto remove_transform(this Scene& self, flecs::entity entity) -> void;

auto run_deferred_functions(this Scene& self) -> void;
};
} // namespace ox
6 changes: 1 addition & 5 deletions Oxylus/include/Scripting/LuaImGuiBindings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2506,8 +2506,6 @@ inline void init_enums(sol::state* lua) {
ImGuiTreeNodeFlags_Selected,
"Framed",
ImGuiTreeNodeFlags_Framed,
"AllowItemOverlap",
ImGuiTreeNodeFlags_AllowItemOverlap,
"NoTreePushOnOpen",
ImGuiTreeNodeFlags_NoTreePushOnOpen,
"NoAutoOpenOnLog",
Expand Down Expand Up @@ -2545,9 +2543,7 @@ inline void init_enums(sol::state* lua) {
"AllowDoubleClick",
ImGuiSelectableFlags_AllowDoubleClick,
"Disabled",
ImGuiSelectableFlags_Disabled,
"AllowItemOverlap",
ImGuiSelectableFlags_AllowItemOverlap);
ImGuiSelectableFlags_Disabled);
#pragma endregion Selectable Flags

#pragma region Popup Flags
Expand Down
5 changes: 3 additions & 2 deletions Oxylus/include/UI/PayloadData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

namespace ox {
struct PayloadData {
static constexpr auto DRAG_DROP_TARGET = "CONTENT_BROWSER_ITEM_TARGET";
static constexpr auto DRAG_DROP_SOURCE = "CONTENT_BROWSER_ITEM_SOURCE";
static constexpr auto DRAG_DROP_TARGET = "DRAG_DROP_TARGET";
static constexpr auto DRAG_DROP_SOURCE = "DRAG_DROP_SOURCE";

char str[256] = {};
UUID uuid = {};
Expand All @@ -24,6 +24,7 @@ struct PayloadData {
auto size() const -> usize { return sizeof(PayloadData); }

auto get_str() const -> std::string { return std::string(str); }
auto get_path() const -> std::filesystem::path { return std::filesystem::path(str); }

static auto from_payload(const ImGuiPayload* payload) -> const PayloadData* {
return reinterpret_cast<const PayloadData*>(payload->Data);
Expand Down
56 changes: 21 additions & 35 deletions Oxylus/src/Physics/Physics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include "Utils/Log.hpp"
#include "Utils/OxMath.hpp"


namespace ox {
static void TraceImpl(const char* inFMT, ...) {
va_list list;
Expand All @@ -30,6 +29,8 @@ static bool AssertFailedImpl(const char* inExpression, const char* inMessage, co
#endif

auto Physics::init() -> std::expected<void, std::string> {
ZoneScoped;

// TODO: Override default allocators with Oxylus allocators.
JPH::RegisterDefaultAllocator();

Expand All @@ -42,59 +43,44 @@ auto Physics::init() -> std::expected<void, std::string> {
JPH::Factory::sInstance = new JPH::Factory();
JPH::RegisterTypes();

debug_renderer = new PhysicsDebugRenderer();

temp_allocator = new JPH::TempAllocatorImpl(10 * 1024 * 1024);
temp_allocator = std::make_unique<JPH::TempAllocatorImpl>(10 * 1024 * 1024);

job_system = new JPH::JobSystemThreadPool();
job_system = std::make_unique<JPH::JobSystemThreadPool>();
job_system->Init(JPH::cMaxPhysicsJobs, JPH::cMaxPhysicsBarriers, (int)std::thread::hardware_concurrency() - 1);
physics_system = new JPH::PhysicsSystem();
physics_system->Init(
MAX_BODIES,
0,
MAX_BODY_PAIRS,
MAX_CONTACT_CONSTRAINS,
layer_interface,
object_vs_broad_phase_layer_filter_interface,
object_layer_pair_filter_interface
);

return {};
}

auto Physics::deinit() -> std::expected<void, std::string> {
ZoneScoped;

JPH::UnregisterTypes();
delete JPH::Factory::sInstance;
JPH::Factory::sInstance = nullptr;
delete temp_allocator;
delete physics_system;
delete job_system;
delete debug_renderer;

return {};
}

void Physics::step(float physicsTs) {
auto Physics::new_system() const -> std::unique_ptr<JPH::PhysicsSystem> {
ZoneScoped;

OX_CHECK_NULL(physics_system, "Physics system not initialized");

physics_system->Update(physicsTs, 1, temp_allocator, job_system);
}

void Physics::debug_draw() {
JPH::BodyManager::DrawSettings settings{};
settings.mDrawShape = true;
settings.mDrawShapeWireframe = true;
auto sys = std::make_unique<JPH::PhysicsSystem>();
sys->Init(
MAX_BODIES,
0,
MAX_BODY_PAIRS,
MAX_CONTACT_CONSTRAINS,
layer_interface,
object_vs_broad_phase_layer_filter_interface,
object_layer_pair_filter_interface
);

physics_system->DrawBodies(settings, debug_renderer);
return sys;
}

JPH::AllHitCollisionCollector<JPH::RayCastBodyCollector> Physics::cast_ray(const RayCast& ray_cast) {
JPH::AllHitCollisionCollector<JPH::RayCastBodyCollector> collector;
const JPH::RayCast ray{math::to_jolt(ray_cast.get_origin()), math::to_jolt(ray_cast.get_direction())};
get_broad_phase_query().CastRay(ray, collector);
auto Physics::new_debug_renderer() const -> std::unique_ptr<PhysicsDebugRenderer> {
ZoneScoped;

return collector;
return std::make_unique<PhysicsDebugRenderer>();
}
} // namespace ox
12 changes: 12 additions & 0 deletions Oxylus/src/Render/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,4 +411,16 @@ auto Renderer::deinit(this Renderer& self) -> std::expected<void, std::string> {

return {};
}

auto Renderer::new_frame(this Renderer& self) -> void {
self.acquired_sky_transmittance_lut_view = self.sky_transmittance_lut_view.acquire(
"sky_transmittance_lut",
vuk::Access::eComputeSampled
);
self.acquired_sky_multiscatter_lut_view = self.sky_multiscatter_lut_view.acquire(
"sky_multiscatter_lut",
vuk::Access::eComputeSampled
);
self.acquired_hilbert_noise_lut = self.hilbert_noise_lut.acquire("hilbert noise", vuk::eComputeSampled);
}
} // namespace ox
Loading