Adding basic impl of Jolt

Update positions on 60tps, position of objects can be modified while
physic simulation is running. Position is owned by transform comps but
the truth is held by the physics engine for affected entities
This commit is contained in:
Erris
2026-03-04 10:19:46 +01:00
parent 282eeeabda
commit eaef554b10
12 changed files with 518 additions and 90 deletions

View File

@@ -3,9 +3,15 @@
#include <open_engine.hpp>
#include "open_engine/renderer/renderer3d.hpp"
#include "open_engine/scene/components.hpp"
#include "panels/content_browser.hpp"
#include "panels/scene_hierarchy.hpp"
#include <Jolt/Physics/Collision/Shape/Shape.h>
#include <Jolt/Math/Real.h>
#include <Jolt/Math/Vec3.h>
#include <Jolt/Physics/Body/BodyCreationSettings.h>
#include <glm/ext/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/matrix.hpp>
@@ -95,12 +101,12 @@ namespace OpenEngine {
// =============================================
Entity cube = scene->CreateEntity("cube");
cube.AddComponent<TransformComponent>();
auto& tc = cube.AddComponent<TransformComponent>();
Ref<Mesh> mesh = CreateCube(cube);
cube.AddComponent<MeshComponent>(mesh);
auto& mc = cube.AddComponent<MeshComponent>(mesh);
mc.primitive_type = PrimitiveType::Cube;
// =============================================
Entity quad = scene->CreateEntity("quad");
@@ -109,7 +115,8 @@ namespace OpenEngine {
Ref<Mesh> quad_mesh = CreateQuad(quad, true);
quad.AddComponent<MeshComponent>(quad_mesh);
auto& mc3 = quad.AddComponent<MeshComponent>(quad_mesh);
mc3.primitive_type = PrimitiveType::Quad;
// =============================================
Entity cube2 = scene->CreateEntity("cube2");
@@ -118,7 +125,8 @@ namespace OpenEngine {
Ref<Mesh> mesh2 = CreateCube(cube2);
cube2.AddComponent<MeshComponent>(mesh2);
auto& mc2 = cube2.AddComponent<MeshComponent>(mesh2);
mc2.primitive_type = PrimitiveType::Cube;
/*
auto view = scene->GetRegistry().view<TagComponent>();
@@ -562,10 +570,12 @@ namespace OpenEngine {
void OnScenePlay()
{
state = PlayState::Play;
scene->OnRuntimeStart();
}
void OnSceneStop()
{
state = PlayState::Edit;
scene->OnRuntimeStop();
}
private:

View File

@@ -18,6 +18,8 @@ namespace OpenEngine {
void CameraOnImGuiRender(entt::registry& registry, entt::entity entity);
void MeshOnImGuiRender(entt::registry&registry, entt::entity entity);
void MaterialOnImGuiRender(entt::registry& registry, entt::entity entity);
void BodyOnImGuiRender(entt::registry& registry, entt::entity entity);
void ShapeOnImGuiRender(entt::registry& registry, entt::entity entity);
}
#endif // EDITOR_COMPONENT_HPP

View File

@@ -95,6 +95,7 @@ namespace OpenEngine {
if (ImGui::InputText("##tagEditor", buffer, sizeof(buffer), ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)
|| (!ImGui::IsItemActive() && ImGui::IsMouseClicked(0)))
tag = buffer;
ImGui::Spacing();
};
void TransformOnImGuiRender(entt::registry& registry, entt::entity entity)
@@ -221,16 +222,27 @@ namespace OpenEngine {
{
auto& material = registry.get<MaterialComponent>(entity).material;
auto& albedo = material.albedo;
auto& roughness = material.roughness;
auto& metallic = material.metallic;
auto& ambient = material.ambient_strength;
auto& specular = material.specular_strength;
ImGui::SliderFloat4("Albedo", glm::value_ptr(material.albedo), 0, 1);
ImGui::SliderFloat("Roughness", &material.roughness, 0, 1);
ImGui::SliderFloat("Metallic", &material.metallic, 0, 1);
ImGui::SliderFloat("Ambient strength", &material.ambient_strength, 0, 1);
ImGui::SliderFloat("Specular strength", &material.specular_strength, 0, 10);
}
ImGui::SliderFloat4("Albedo", glm::value_ptr(albedo), 0, 1);
ImGui::SliderFloat("Roughness", &roughness, 0, 1);
ImGui::SliderFloat("Metallic", &metallic, 0, 1);
ImGui::SliderFloat("Ambient strength", &ambient, 0, 1);
ImGui::SliderFloat("Specular strength", &specular, 0, 10);
void BodyOnImGuiRender(entt::registry &registry, entt::entity entity)
{
auto& body_comp = registry.get<PhysicsBodyComponent>(entity);
ImGui::SliderFloat("Linear damping", &body_comp.linear_damping, 0, 1);
ImGui::SliderFloat("Angular damping", &body_comp.angular_damping, 0, 1);
ImGui::SliderFloat("Gravity factor", &body_comp.gravity_factor, 0, 1);
}
void ShapeOnImGuiRender(entt::registry &registry, entt::entity entity)
{
auto& shape_comp = registry.get<PhysicsShapeComponent>(entity);
ImGui::SliderFloat("Bounciness", &shape_comp.restitution, 0, 1);
ImGui::SliderFloat("Friction", &shape_comp.friction, 0, 1);
}
}

View File

@@ -24,6 +24,8 @@ namespace OpenEngine {
RegisterDrawer<CameraComponent>("Camera", &CameraOnImGuiRender);
RegisterDrawer<MeshComponent>("Mesh", &MeshOnImGuiRender);
RegisterDrawer<MaterialComponent>("Material", &MaterialOnImGuiRender);
RegisterDrawer<PhysicsBodyComponent>("Physics Body", &BodyOnImGuiRender);
RegisterDrawer<PhysicsShapeComponent>("Physics Shape", &ShapeOnImGuiRender);
scene = context;
selected_context = {};
@@ -57,6 +59,16 @@ namespace OpenEngine {
selected_context.AddComponent<MaterialComponent>();
ImGui::CloseCurrentPopup();
}
if (!selected_context.HasComponent<PhysicsBodyComponent>())
if (ImGui::MenuItem("Physics body")) {
selected_context.AddComponent<PhysicsBodyComponent>();
ImGui::CloseCurrentPopup();
}
if (!selected_context.HasComponent<PhysicsShapeComponent>())
if (ImGui::MenuItem("Physics shape")) {
selected_context.AddComponent<PhysicsShapeComponent>();
ImGui::CloseCurrentPopup();
}
}
void EntityPopup(Ref<Scene>& scene)
@@ -201,17 +213,18 @@ namespace OpenEngine {
void SceneHierarchy::DrawComponents(Entity& entity)
{
auto& reg = scene->GetRegistry();
entt::entity handle = selected_context;
entt::entity handle = entity;
if (!selected_context || !entity)
if (!entity)
return;
entity.GetComponents<TagComponent>();
TagOnImGuiRender(reg, entity);
// TODO: Defer deletion like the entities?
std::vector<entt::id_type> pending_deletion; // 0 is null/invalid in entt usually
std::vector<entt::id_type> component_to_delete; // 0 is null/invalid in entt usually
// Iterate through every component type entt knows about
// Iterate through every component type entt knows about
for (auto [id, storage] : reg.storage()) {
if (storage.contains(handle)) {
if (drawers.contains(id)) {
@@ -234,20 +247,24 @@ namespace OpenEngine {
if (ImGui::BeginPopup("component_settings")) {
if (ImGui::MenuItem("Remove component"))
component_to_delete.emplace_back(id);
pending_deletion.emplace_back(id);
ImGui::EndPopup();
}
if (opened) {
ImGui::Spacing();
drawers[id].draw_func(reg, handle);
ImGui::Spacing();
ImGui::TreePop();
}
}
}
}
for (auto& id : component_to_delete)
for (auto& id : pending_deletion) {
drawers[id].remove_func(reg, entity);
pending_deletion.clear();
}
}
}