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:
@@ -3,9 +3,15 @@
|
|||||||
|
|
||||||
#include <open_engine.hpp>
|
#include <open_engine.hpp>
|
||||||
|
|
||||||
|
#include "open_engine/renderer/renderer3d.hpp"
|
||||||
|
#include "open_engine/scene/components.hpp"
|
||||||
#include "panels/content_browser.hpp"
|
#include "panels/content_browser.hpp"
|
||||||
#include "panels/scene_hierarchy.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/ext/matrix_transform.hpp>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
#include <glm/matrix.hpp>
|
#include <glm/matrix.hpp>
|
||||||
@@ -95,12 +101,12 @@ namespace OpenEngine {
|
|||||||
// =============================================
|
// =============================================
|
||||||
Entity cube = scene->CreateEntity("cube");
|
Entity cube = scene->CreateEntity("cube");
|
||||||
|
|
||||||
|
auto& tc = cube.AddComponent<TransformComponent>();
|
||||||
cube.AddComponent<TransformComponent>();
|
|
||||||
|
|
||||||
Ref<Mesh> mesh = CreateCube(cube);
|
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");
|
Entity quad = scene->CreateEntity("quad");
|
||||||
@@ -109,7 +115,8 @@ namespace OpenEngine {
|
|||||||
|
|
||||||
Ref<Mesh> quad_mesh = CreateQuad(quad, true);
|
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");
|
Entity cube2 = scene->CreateEntity("cube2");
|
||||||
@@ -118,7 +125,8 @@ namespace OpenEngine {
|
|||||||
|
|
||||||
Ref<Mesh> mesh2 = CreateCube(cube2);
|
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>();
|
auto view = scene->GetRegistry().view<TagComponent>();
|
||||||
@@ -562,10 +570,12 @@ namespace OpenEngine {
|
|||||||
void OnScenePlay()
|
void OnScenePlay()
|
||||||
{
|
{
|
||||||
state = PlayState::Play;
|
state = PlayState::Play;
|
||||||
|
scene->OnRuntimeStart();
|
||||||
}
|
}
|
||||||
void OnSceneStop()
|
void OnSceneStop()
|
||||||
{
|
{
|
||||||
state = PlayState::Edit;
|
state = PlayState::Edit;
|
||||||
|
scene->OnRuntimeStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ namespace OpenEngine {
|
|||||||
void CameraOnImGuiRender(entt::registry& registry, entt::entity entity);
|
void CameraOnImGuiRender(entt::registry& registry, entt::entity entity);
|
||||||
void MeshOnImGuiRender(entt::registry®istry, entt::entity entity);
|
void MeshOnImGuiRender(entt::registry®istry, entt::entity entity);
|
||||||
void MaterialOnImGuiRender(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
|
#endif // EDITOR_COMPONENT_HPP
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ namespace OpenEngine {
|
|||||||
if (ImGui::InputText("##tagEditor", buffer, sizeof(buffer), ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)
|
if (ImGui::InputText("##tagEditor", buffer, sizeof(buffer), ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)
|
||||||
|| (!ImGui::IsItemActive() && ImGui::IsMouseClicked(0)))
|
|| (!ImGui::IsItemActive() && ImGui::IsMouseClicked(0)))
|
||||||
tag = buffer;
|
tag = buffer;
|
||||||
|
ImGui::Spacing();
|
||||||
};
|
};
|
||||||
|
|
||||||
void TransformOnImGuiRender(entt::registry& registry, entt::entity entity)
|
void TransformOnImGuiRender(entt::registry& registry, entt::entity entity)
|
||||||
@@ -221,16 +222,27 @@ namespace OpenEngine {
|
|||||||
{
|
{
|
||||||
auto& material = registry.get<MaterialComponent>(entity).material;
|
auto& material = registry.get<MaterialComponent>(entity).material;
|
||||||
|
|
||||||
auto& albedo = material.albedo;
|
ImGui::SliderFloat4("Albedo", glm::value_ptr(material.albedo), 0, 1);
|
||||||
auto& roughness = material.roughness;
|
ImGui::SliderFloat("Roughness", &material.roughness, 0, 1);
|
||||||
auto& metallic = material.metallic;
|
ImGui::SliderFloat("Metallic", &material.metallic, 0, 1);
|
||||||
auto& ambient = material.ambient_strength;
|
ImGui::SliderFloat("Ambient strength", &material.ambient_strength, 0, 1);
|
||||||
auto& specular = material.specular_strength;
|
ImGui::SliderFloat("Specular strength", &material.specular_strength, 0, 10);
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::SliderFloat4("Albedo", glm::value_ptr(albedo), 0, 1);
|
void BodyOnImGuiRender(entt::registry ®istry, entt::entity entity)
|
||||||
ImGui::SliderFloat("Roughness", &roughness, 0, 1);
|
{
|
||||||
ImGui::SliderFloat("Metallic", &metallic, 0, 1);
|
auto& body_comp = registry.get<PhysicsBodyComponent>(entity);
|
||||||
ImGui::SliderFloat("Ambient strength", &ambient, 0, 1);
|
|
||||||
ImGui::SliderFloat("Specular strength", &specular, 0, 10);
|
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 ®istry, 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ namespace OpenEngine {
|
|||||||
RegisterDrawer<CameraComponent>("Camera", &CameraOnImGuiRender);
|
RegisterDrawer<CameraComponent>("Camera", &CameraOnImGuiRender);
|
||||||
RegisterDrawer<MeshComponent>("Mesh", &MeshOnImGuiRender);
|
RegisterDrawer<MeshComponent>("Mesh", &MeshOnImGuiRender);
|
||||||
RegisterDrawer<MaterialComponent>("Material", &MaterialOnImGuiRender);
|
RegisterDrawer<MaterialComponent>("Material", &MaterialOnImGuiRender);
|
||||||
|
RegisterDrawer<PhysicsBodyComponent>("Physics Body", &BodyOnImGuiRender);
|
||||||
|
RegisterDrawer<PhysicsShapeComponent>("Physics Shape", &ShapeOnImGuiRender);
|
||||||
|
|
||||||
scene = context;
|
scene = context;
|
||||||
selected_context = {};
|
selected_context = {};
|
||||||
@@ -57,6 +59,16 @@ namespace OpenEngine {
|
|||||||
selected_context.AddComponent<MaterialComponent>();
|
selected_context.AddComponent<MaterialComponent>();
|
||||||
ImGui::CloseCurrentPopup();
|
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)
|
void EntityPopup(Ref<Scene>& scene)
|
||||||
@@ -201,17 +213,18 @@ namespace OpenEngine {
|
|||||||
void SceneHierarchy::DrawComponents(Entity& entity)
|
void SceneHierarchy::DrawComponents(Entity& entity)
|
||||||
{
|
{
|
||||||
auto& reg = scene->GetRegistry();
|
auto& reg = scene->GetRegistry();
|
||||||
entt::entity handle = selected_context;
|
entt::entity handle = entity;
|
||||||
|
|
||||||
if (!selected_context || !entity)
|
if (!entity)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
entity.GetComponents<TagComponent>();
|
entity.GetComponents<TagComponent>();
|
||||||
TagOnImGuiRender(reg, entity);
|
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()) {
|
for (auto [id, storage] : reg.storage()) {
|
||||||
if (storage.contains(handle)) {
|
if (storage.contains(handle)) {
|
||||||
if (drawers.contains(id)) {
|
if (drawers.contains(id)) {
|
||||||
@@ -234,20 +247,24 @@ namespace OpenEngine {
|
|||||||
|
|
||||||
if (ImGui::BeginPopup("component_settings")) {
|
if (ImGui::BeginPopup("component_settings")) {
|
||||||
if (ImGui::MenuItem("Remove component"))
|
if (ImGui::MenuItem("Remove component"))
|
||||||
component_to_delete.emplace_back(id);
|
pending_deletion.emplace_back(id);
|
||||||
|
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opened) {
|
if (opened) {
|
||||||
|
ImGui::Spacing();
|
||||||
drawers[id].draw_func(reg, handle);
|
drawers[id].draw_func(reg, handle);
|
||||||
|
ImGui::Spacing();
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& id : component_to_delete)
|
for (auto& id : pending_deletion) {
|
||||||
drawers[id].remove_func(reg, entity);
|
drawers[id].remove_func(reg, entity);
|
||||||
|
pending_deletion.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
20
imgui.ini
20
imgui.ini
@@ -1,6 +1,6 @@
|
|||||||
[Window][WindowOverViewport_11111111]
|
[Window][WindowOverViewport_11111111]
|
||||||
Pos=0,24
|
Pos=0,24
|
||||||
Size=1272,1363
|
Size=2552,1363
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
[Window][Debug##Default]
|
[Window][Debug##Default]
|
||||||
@@ -15,19 +15,19 @@ Collapsed=0
|
|||||||
DockId=0x00000003,0
|
DockId=0x00000003,0
|
||||||
|
|
||||||
[Window][Properties]
|
[Window][Properties]
|
||||||
Pos=822,24
|
Pos=2102,24
|
||||||
Size=450,805
|
Size=450,805
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000007,0
|
DockId=0x00000007,0
|
||||||
|
|
||||||
[Window][Viewport]
|
[Window][Viewport]
|
||||||
Pos=226,61
|
Pos=226,61
|
||||||
Size=594,956
|
Size=1874,956
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000012,0
|
DockId=0x00000012,0
|
||||||
|
|
||||||
[Window][Dear ImGui Demo]
|
[Window][Dear ImGui Demo]
|
||||||
Pos=822,831
|
Pos=2102,831
|
||||||
Size=450,556
|
Size=450,556
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000008,0
|
DockId=0x00000008,0
|
||||||
@@ -144,7 +144,7 @@ DockId=0x00000012,1
|
|||||||
|
|
||||||
[Window][Assets]
|
[Window][Assets]
|
||||||
Pos=226,1019
|
Pos=226,1019
|
||||||
Size=594,368
|
Size=1874,368
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x0000000C,0
|
DockId=0x0000000C,0
|
||||||
|
|
||||||
@@ -156,12 +156,12 @@ DockId=0x0000000F,0
|
|||||||
|
|
||||||
[Window][##play_state_bar]
|
[Window][##play_state_bar]
|
||||||
Pos=226,24
|
Pos=226,24
|
||||||
Size=594,35
|
Size=1874,35
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000011,0
|
DockId=0x00000011,0
|
||||||
|
|
||||||
[Docking][Data]
|
[Docking][Data]
|
||||||
DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,24 Size=1272,1363 Split=X
|
DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,24 Size=2552,1363 Split=X
|
||||||
DockNode ID=0x00000005 Parent=0x08BD597D SizeRef=820,1386 Split=X
|
DockNode ID=0x00000005 Parent=0x08BD597D SizeRef=820,1386 Split=X
|
||||||
DockNode ID=0x00000001 Parent=0x00000005 SizeRef=224,1386 Split=Y Selected=0xE601B12F
|
DockNode ID=0x00000001 Parent=0x00000005 SizeRef=224,1386 Split=Y Selected=0xE601B12F
|
||||||
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=255,417 Selected=0x553E127E
|
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=255,417 Selected=0x553E127E
|
||||||
@@ -173,11 +173,11 @@ DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,24 Size=1272,1363
|
|||||||
DockNode ID=0x0000000F Parent=0x0000000D SizeRef=594,60 Selected=0x8325EBDA
|
DockNode ID=0x0000000F Parent=0x0000000D SizeRef=594,60 Selected=0x8325EBDA
|
||||||
DockNode ID=0x00000010 Parent=0x0000000D SizeRef=594,931 Split=Y Selected=0xC450F867
|
DockNode ID=0x00000010 Parent=0x0000000D SizeRef=594,931 Split=Y Selected=0xC450F867
|
||||||
DockNode ID=0x00000011 Parent=0x00000010 SizeRef=594,35 HiddenTabBar=1 Selected=0xAB37695D
|
DockNode ID=0x00000011 Parent=0x00000010 SizeRef=594,35 HiddenTabBar=1 Selected=0xAB37695D
|
||||||
DockNode ID=0x00000012 Parent=0x00000010 SizeRef=594,956 CentralNode=1 Selected=0xC450F867
|
DockNode ID=0x00000012 Parent=0x00000010 SizeRef=594,964 CentralNode=1 Selected=0xC450F867
|
||||||
DockNode ID=0x0000000E Parent=0x0000000B SizeRef=800,993 Selected=0x3EEA4247
|
DockNode ID=0x0000000E Parent=0x0000000B SizeRef=800,993 Selected=0x3EEA4247
|
||||||
DockNode ID=0x0000000C Parent=0x00000009 SizeRef=409,368 Selected=0x42C24103
|
DockNode ID=0x0000000C Parent=0x00000009 SizeRef=409,368 Selected=0x42C24103
|
||||||
DockNode ID=0x0000000A Parent=0x00000002 SizeRef=483,600 Selected=0x1BCA3180
|
DockNode ID=0x0000000A Parent=0x00000002 SizeRef=483,600 Selected=0x1BCA3180
|
||||||
DockNode ID=0x00000006 Parent=0x08BD597D SizeRef=450,1386 Split=Y Selected=0x8C72BEA8
|
DockNode ID=0x00000006 Parent=0x08BD597D SizeRef=450,1386 Split=Y Selected=0x8C72BEA8
|
||||||
DockNode ID=0x00000007 Parent=0x00000006 SizeRef=444,769 Selected=0x8C72BEA8
|
DockNode ID=0x00000007 Parent=0x00000006 SizeRef=444,810 Selected=0x8C72BEA8
|
||||||
DockNode ID=0x00000008 Parent=0x00000006 SizeRef=444,531 Selected=0x5E5F7166
|
DockNode ID=0x00000008 Parent=0x00000006 SizeRef=444,559 Selected=0x5E5F7166
|
||||||
|
|
||||||
|
|||||||
188
open_engine/include/open_engine/physics.hpp
Normal file
188
open_engine/include/open_engine/physics.hpp
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
#ifndef PHYSICS_HPP
|
||||||
|
#define PHYSICS_HPP
|
||||||
|
|
||||||
|
#include "logging.hpp"
|
||||||
|
|
||||||
|
#include <Jolt/Jolt.h>
|
||||||
|
#include <Jolt/Physics/Body/BodyInterface.h>
|
||||||
|
#include <Jolt/RegisterTypes.h>
|
||||||
|
#include <Jolt/Core/Factory.h>
|
||||||
|
#include <Jolt/Core/TempAllocator.h>
|
||||||
|
#include <Jolt/Core/JobSystemThreadPool.h>
|
||||||
|
#include <Jolt/Physics/PhysicsSettings.h>
|
||||||
|
#include <Jolt/Physics/PhysicsSystem.h>
|
||||||
|
#include <Jolt/Physics/Collision/Shape/BoxShape.h>
|
||||||
|
#include <Jolt/Physics/Collision/Shape/SphereShape.h>
|
||||||
|
#include <Jolt/Physics/Body/BodyCreationSettings.h>
|
||||||
|
#include <Jolt/Physics/Body/BodyActivationListener.h>
|
||||||
|
|
||||||
|
#include <cstdarg>
|
||||||
|
|
||||||
|
using namespace JPH;
|
||||||
|
using namespace JPH::literals;
|
||||||
|
|
||||||
|
// Callback for traces, connect this to your own trace function if you have one
|
||||||
|
static void TraceImpl(const char *in_fmt, ...)
|
||||||
|
{
|
||||||
|
// Format the message
|
||||||
|
va_list list;
|
||||||
|
va_start(list, in_fmt);
|
||||||
|
char buffer[1024];
|
||||||
|
vsnprintf(buffer, sizeof(buffer), in_fmt, list);
|
||||||
|
va_end(list);
|
||||||
|
|
||||||
|
OE_CORE_TRACE("Jolt: {}", buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef JPH_ENABLE_ASSERTS
|
||||||
|
// Callback for asserts, connect this to your own assert handler if you have one
|
||||||
|
static bool AssertFailedImpl(const char *in_expression, const char *in_message, const char *in_file, uint in_line)
|
||||||
|
{
|
||||||
|
OE_CORE_ERROR("Jolt: Assert in file: {}:{} :({}) {}", in_file, in_line, in_expression, (in_message != nullptr? in_message : ""));
|
||||||
|
|
||||||
|
// Breakpoint
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
#endif // JPH_ENABLE_ASSERTS
|
||||||
|
|
||||||
|
// Layer that objects can be in, determines which other objects it can collide with
|
||||||
|
// Typically you at least want to have 1 layer for moving bodies and 1 layer for static bodies, but you can have more
|
||||||
|
// layers if you want. E.g. you could have a layer for high detail collision (which is not used by the physics simulation
|
||||||
|
// but only if you do collision testing).
|
||||||
|
namespace Layers {
|
||||||
|
static constexpr ObjectLayer NON_MOVING = 0;
|
||||||
|
static constexpr ObjectLayer MOVING = 1;
|
||||||
|
static constexpr ObjectLayer NUM_LAYERS = 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ObjectLayerPairFilterImpl : public ObjectLayerPairFilter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool ShouldCollide(ObjectLayer object1, ObjectLayer object2) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Each broadphase layer results in a separate bounding volume tree in the broad phase. You at least want to have
|
||||||
|
// a layer for non-moving and moving objects to avoid having to update a tree full of static objects every frame.
|
||||||
|
// You can have a 1-on-1 mapping between object layers and broadphase layers (like in this case) but if you have
|
||||||
|
// many object layers you'll be creating many broad phase trees, which is not efficient. If you want to fine tune
|
||||||
|
// your broadphase layers define JPH_TRACK_BROADPHASE_STATS and look at the stats reported on the TTY.
|
||||||
|
namespace BroadPhaseLayers
|
||||||
|
{
|
||||||
|
static constexpr BroadPhaseLayer NON_MOVING(0);
|
||||||
|
static constexpr BroadPhaseLayer MOVING(1);
|
||||||
|
static constexpr uint NUM_LAYERS(2);
|
||||||
|
};
|
||||||
|
|
||||||
|
class BPLayerInterfaceImpl final : public BroadPhaseLayerInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BPLayerInterfaceImpl()
|
||||||
|
{
|
||||||
|
object_to_broad_phase[Layers::NON_MOVING] = BroadPhaseLayers::NON_MOVING;
|
||||||
|
object_to_broad_phase[Layers::MOVING] = BroadPhaseLayers::MOVING;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual uint GetNumBroadPhaseLayers() const override { return BroadPhaseLayers::NUM_LAYERS; };
|
||||||
|
|
||||||
|
virtual BroadPhaseLayer GetBroadPhaseLayer(ObjectLayer layer) const override
|
||||||
|
{
|
||||||
|
JPH_ASSERT(layer < Layers::NUM_LAYERS);
|
||||||
|
return object_to_broad_phase[layer];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
BroadPhaseLayer object_to_broad_phase[Layers::NUM_LAYERS];
|
||||||
|
};
|
||||||
|
|
||||||
|
class ObjectVsBroadPhaseLayerFilterImpl : public ObjectVsBroadPhaseLayerFilter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool ShouldCollide(ObjectLayer layer1, BroadPhaseLayer layer2) const override
|
||||||
|
{
|
||||||
|
switch (layer1)
|
||||||
|
{
|
||||||
|
case Layers::NON_MOVING:
|
||||||
|
return layer2 == BroadPhaseLayers::MOVING;
|
||||||
|
case Layers::MOVING:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
JPH_ASSERT(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// An example contact listener
|
||||||
|
class MyContactListener : public ContactListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// See: ContactListener
|
||||||
|
virtual ValidateResult OnContactValidate(const Body &inBody1, const Body &inBody2, RVec3Arg inBaseOffset, const CollideShapeResult &inCollisionResult) override
|
||||||
|
{
|
||||||
|
OE_CORE_TRACE("Jolt: Contact validate callback");
|
||||||
|
|
||||||
|
// Allows you to ignore a contact before it is created (using layers to not make objects collide is cheaper!)
|
||||||
|
return ValidateResult::AcceptAllContactsForThisBodyPair;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void OnContactAdded(const Body &inBody1, const Body &inBody2, const ContactManifold &inManifold, ContactSettings &ioSettings) override
|
||||||
|
{
|
||||||
|
OE_CORE_TRACE("Jolt: A contact was added");
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void OnContactPersisted(const Body &inBody1, const Body &inBody2, const ContactManifold &inManifold, ContactSettings &ioSettings) override
|
||||||
|
{
|
||||||
|
OE_CORE_TRACE("Jolt: A contact was persisted");
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void OnContactRemoved(const SubShapeIDPair &inSubShapePair) override
|
||||||
|
{
|
||||||
|
OE_CORE_TRACE("Jolt: A contact was removed");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// An example activation listener
|
||||||
|
class MyBodyActivationListener : public BodyActivationListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void OnBodyActivated(const BodyID &inBodyID, uint64 inBodyUserData) override
|
||||||
|
{
|
||||||
|
OE_CORE_TRACE("Jolt: A body got activated");
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void OnBodyDeactivated(const BodyID &inBodyID, uint64 inBodyUserData) override
|
||||||
|
{
|
||||||
|
OE_CORE_TRACE("Jolt: A body went to sleep");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace OpenEngine {
|
||||||
|
|
||||||
|
// Consider making this static like the renderer
|
||||||
|
class PhysicsEngine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PhysicsEngine();
|
||||||
|
~PhysicsEngine();
|
||||||
|
|
||||||
|
// TODO: Temp, make abstract function to create a body
|
||||||
|
BodyInterface& GetBodyInterface() { return physics_system.GetBodyInterface(); };
|
||||||
|
void Update( float delta_time, int collision_steps);
|
||||||
|
|
||||||
|
private:
|
||||||
|
PhysicsSystem physics_system;
|
||||||
|
|
||||||
|
Ref<TempAllocatorImpl> tmp_allocator;
|
||||||
|
Ref<JobSystemThreadPool> job_system;
|
||||||
|
|
||||||
|
MyBodyActivationListener body_activation_listener;
|
||||||
|
MyContactListener contact_listener;
|
||||||
|
|
||||||
|
BPLayerInterfaceImpl broad_phase_layer_interface;
|
||||||
|
ObjectVsBroadPhaseLayerFilterImpl object_vs_broadphase_layer_filter;
|
||||||
|
ObjectLayerPairFilterImpl object_vs_object_layer_filter;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PHYSICS_HPP
|
||||||
@@ -6,7 +6,14 @@
|
|||||||
#include "open_engine/scene/scene_camera.hpp"
|
#include "open_engine/scene/scene_camera.hpp"
|
||||||
#include "open_engine/renderer/texture.hpp"
|
#include "open_engine/renderer/texture.hpp"
|
||||||
#include "open_engine/renderer/renderer3d.hpp"
|
#include "open_engine/renderer/renderer3d.hpp"
|
||||||
|
#include "open_engine/physics.hpp"
|
||||||
|
|
||||||
|
#include <Jolt/Physics/Body/BodyCreationSettings.h>
|
||||||
|
#include <Jolt/Physics/Body/BodyInterface.h>
|
||||||
|
#include <Jolt/Physics/Body/MotionType.h>
|
||||||
|
#include <Jolt/Physics/Collision/ObjectLayer.h>
|
||||||
|
#include <Jolt/Physics/Collision/Shape/Shape.h>
|
||||||
|
#include <Jolt/Physics/EActivation.h>
|
||||||
#include <glm/ext/matrix_transform.hpp>
|
#include <glm/ext/matrix_transform.hpp>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
#include <glm/fwd.hpp>
|
#include <glm/fwd.hpp>
|
||||||
@@ -110,6 +117,32 @@ namespace OpenEngine {
|
|||||||
: material(material) {};
|
: material(material) {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PhysicsBodyComponent
|
||||||
|
{
|
||||||
|
enum class BodyType { Static = 0, Kinematic, Dynamic };
|
||||||
|
|
||||||
|
BodyID body;
|
||||||
|
|
||||||
|
BodyType type = BodyType::Dynamic;
|
||||||
|
|
||||||
|
float linear_damping = 0.05f;
|
||||||
|
float angular_damping = 0.05f;
|
||||||
|
float gravity_factor = 1.0f;
|
||||||
|
|
||||||
|
EActivation initial_activation_state = EActivation::Activate;
|
||||||
|
|
||||||
|
PhysicsBodyComponent() = default;
|
||||||
|
PhysicsBodyComponent(const PhysicsBodyComponent&) = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PhysicsShapeComponent
|
||||||
|
{
|
||||||
|
ShapeRefC shape;
|
||||||
|
|
||||||
|
float restitution = 0.8f;
|
||||||
|
float friction = 0.5f;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // COMPONENTS_HPP
|
#endif // COMPONENTS_HPP
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
#define SCENE_HPP
|
#define SCENE_HPP
|
||||||
|
|
||||||
#include "open_engine/renderer/editor_camera.hpp"
|
#include "open_engine/renderer/editor_camera.hpp"
|
||||||
|
#include "open_engine/physics.hpp"
|
||||||
|
|
||||||
|
#include <Jolt/Physics/Body/BodyInterface.h>
|
||||||
#include <entt/entity/fwd.hpp>
|
#include <entt/entity/fwd.hpp>
|
||||||
#include <entt/entt.hpp>
|
#include <entt/entt.hpp>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@@ -17,6 +19,9 @@ namespace OpenEngine {
|
|||||||
Scene() = default;
|
Scene() = default;
|
||||||
~Scene() = default;
|
~Scene() = default;
|
||||||
|
|
||||||
|
void OnRuntimeStart();
|
||||||
|
void OnRuntimeStop();
|
||||||
|
|
||||||
Entity CreateEntity(const std::string& name = std::string());
|
Entity CreateEntity(const std::string& name = std::string());
|
||||||
void DeleteEntity(entt::entity entity);
|
void DeleteEntity(entt::entity entity);
|
||||||
void MarkEntityForDeletion(Entity entity);
|
void MarkEntityForDeletion(Entity entity);
|
||||||
@@ -28,20 +33,27 @@ namespace OpenEngine {
|
|||||||
void OnViewportResize(uint32_t width, uint32_t height);
|
void OnViewportResize(uint32_t width, uint32_t height);
|
||||||
|
|
||||||
entt::registry& GetRegistry() { return registry; };
|
entt::registry& GetRegistry() { return registry; };
|
||||||
|
PhysicsEngine& GetPhysicsEngine() { return physics_engine; };
|
||||||
Entity GetPrimaryCamera();
|
Entity GetPrimaryCamera();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void OnUpdatePhysics();
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void OnComponentAdded(Entity entity, T& component);
|
void OnComponentAdded(Entity entity, T& component);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
entt::registry registry;
|
entt::registry registry;
|
||||||
|
PhysicsEngine physics_engine;
|
||||||
|
|
||||||
|
BodyInterface* body_interface;
|
||||||
|
|
||||||
uint32_t viewport_width = 0, viewport_height = 0;
|
uint32_t viewport_width = 0, viewport_height = 0;
|
||||||
|
|
||||||
std::vector<entt::entity> pending_deletion;
|
std::vector<entt::entity> pending_deletion;
|
||||||
|
|
||||||
|
//BodyID sphere_id;
|
||||||
|
|
||||||
friend class SceneSerializer;
|
friend class SceneSerializer;
|
||||||
friend class Entity;
|
friend class Entity;
|
||||||
};
|
};
|
||||||
|
|||||||
71
open_engine/src/open_engine/physics.cpp
Normal file
71
open_engine/src/open_engine/physics.cpp
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
#include <pch.hpp>
|
||||||
|
|
||||||
|
#include <ref_scope.hpp>
|
||||||
|
#include <physics.hpp>
|
||||||
|
|
||||||
|
#include <Jolt/Physics/Body/BodyInterface.h>
|
||||||
|
#include <Jolt/Core/JobSystemThreadPool.h>
|
||||||
|
#include <Jolt/Core/Memory.h>
|
||||||
|
#include <Jolt/Physics/PhysicsSystem.h>
|
||||||
|
#include <Jolt/Physics/PhysicsUpdateContext.h>
|
||||||
|
|
||||||
|
bool ObjectLayerPairFilterImpl::ShouldCollide(ObjectLayer object1, ObjectLayer object2) const
|
||||||
|
{
|
||||||
|
switch (object1)
|
||||||
|
{
|
||||||
|
case Layers::NON_MOVING:
|
||||||
|
return object2 == Layers::MOVING; // Non moving only collides with moving
|
||||||
|
case Layers::MOVING:
|
||||||
|
return true; // Moving collides with everything
|
||||||
|
default:
|
||||||
|
JPH_ASSERT(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace OpenEngine {
|
||||||
|
|
||||||
|
PhysicsEngine::PhysicsEngine()
|
||||||
|
{
|
||||||
|
RegisterDefaultAllocator();
|
||||||
|
|
||||||
|
Trace = TraceImpl;
|
||||||
|
JPH_IF_ENABLE_ASSERTS(AssertFailed = AssertFailedImpl);
|
||||||
|
|
||||||
|
Factory::sInstance = new Factory();
|
||||||
|
|
||||||
|
RegisterTypes();
|
||||||
|
|
||||||
|
tmp_allocator = CreateRef<TempAllocatorImpl>(10 * 1024 * 1024);
|
||||||
|
|
||||||
|
job_system = CreateRef<JobSystemThreadPool>(cMaxPhysicsJobs, cMaxPhysicsBarriers, thread::hardware_concurrency() - 1);
|
||||||
|
|
||||||
|
physics_system.Init(
|
||||||
|
1024,
|
||||||
|
0,
|
||||||
|
1024,
|
||||||
|
1024,
|
||||||
|
broad_phase_layer_interface,
|
||||||
|
object_vs_broadphase_layer_filter,
|
||||||
|
object_vs_object_layer_filter);
|
||||||
|
|
||||||
|
physics_system.SetBodyActivationListener(&body_activation_listener);
|
||||||
|
physics_system.SetContactListener(&contact_listener);
|
||||||
|
|
||||||
|
// TODO: Move out of here and check the comment on Jolt's example
|
||||||
|
physics_system.OptimizeBroadPhase();
|
||||||
|
}
|
||||||
|
|
||||||
|
PhysicsEngine::~PhysicsEngine() {
|
||||||
|
UnregisterTypes();
|
||||||
|
|
||||||
|
// Destroy the factory
|
||||||
|
delete Factory::sInstance;
|
||||||
|
Factory::sInstance = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
void PhysicsEngine::Update(float delta_time, int collision_steps)
|
||||||
|
{
|
||||||
|
physics_system.Update(delta_time, collision_steps, &*tmp_allocator, &*job_system);
|
||||||
|
}
|
||||||
|
}
|
||||||
136
open_engine/src/open_engine/scene/scene.cpp
Normal file → Executable file
136
open_engine/src/open_engine/scene/scene.cpp
Normal file → Executable file
@@ -1,14 +1,85 @@
|
|||||||
#include <cstdint>
|
#include "logging.hpp"
|
||||||
#include <entt/entity/fwd.hpp>
|
|
||||||
#include <pch.hpp>
|
#include <pch.hpp>
|
||||||
|
|
||||||
#include <renderer/renderer3d.hpp>
|
#include <renderer/renderer3d.hpp>
|
||||||
#include <scene/components.hpp>
|
#include <scene/components.hpp>
|
||||||
#include <scene/entity.hpp>
|
#include <scene/entity.hpp>
|
||||||
#include <scene/scene.hpp>
|
#include <scene/scene.hpp>
|
||||||
|
#include <core/time.hpp>
|
||||||
|
|
||||||
|
#include <Jolt/Physics/Collision/Shape/Shape.h>
|
||||||
|
#include <Jolt/Physics/Collision/Shape/SphereShape.h>
|
||||||
|
#include <Jolt/Physics/EActivation.h>
|
||||||
|
#include <Jolt/Math/Real.h>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <entt/entity/fwd.hpp>
|
||||||
|
|
||||||
namespace OpenEngine {
|
namespace OpenEngine {
|
||||||
|
|
||||||
|
void Scene::OnRuntimeStart()
|
||||||
|
{
|
||||||
|
body_interface = &physics_engine.GetBodyInterface();
|
||||||
|
|
||||||
|
BoxShapeSettings floor_shape_settings(Vec3(100.0f, 1.0f, 100.0f));
|
||||||
|
floor_shape_settings.SetEmbedded(); // A ref counted object on the stack (base class RefTarget) should be marked as such to prevent it from being freed when its reference count goes to 0.
|
||||||
|
|
||||||
|
// Create the shape
|
||||||
|
ShapeSettings::ShapeResult floor_shape_result = floor_shape_settings.Create();
|
||||||
|
ShapeRefC floor_shape = floor_shape_result.Get(); // We don't expect an error here, but you can check floor_shape_result for HasError() / GetError()
|
||||||
|
|
||||||
|
// Create the settings for the body itself. Note that here you can also set other properties like the restitution / friction.
|
||||||
|
BodyCreationSettings floor_settings(floor_shape, RVec3(0.0_r, -1.0_r, 0.0_r), Quat::sIdentity(), EMotionType::Static, Layers::NON_MOVING);
|
||||||
|
|
||||||
|
// Create the actual rigid body
|
||||||
|
Body *floor = body_interface->CreateBody(floor_settings); // Note that if we run out of bodies this can return nullptr
|
||||||
|
|
||||||
|
// Add it to the world
|
||||||
|
body_interface->AddBody(floor->GetID(), EActivation::DontActivate);
|
||||||
|
|
||||||
|
auto view = registry.view<PhysicsBodyComponent>();
|
||||||
|
for (auto e : view) {
|
||||||
|
Entity entity = { e, this };
|
||||||
|
|
||||||
|
TransformComponent* tc;
|
||||||
|
if (entity.HasComponent<TransformComponent>())
|
||||||
|
tc = &entity.GetComponents<TransformComponent>();
|
||||||
|
auto& pbc = entity.GetComponents<PhysicsBodyComponent>();
|
||||||
|
|
||||||
|
PhysicsShapeComponent* psc;
|
||||||
|
if (entity.HasComponent<PhysicsShapeComponent>())
|
||||||
|
psc = &entity.GetComponents<PhysicsShapeComponent>();
|
||||||
|
|
||||||
|
glm::vec3& pos = tc->translation;
|
||||||
|
BodyCreationSettings settings(
|
||||||
|
new BoxShape(Vec3(0.5f, 0.5f, 0.5f)),
|
||||||
|
Vec3(pos.x, pos.y, pos.z),
|
||||||
|
Quat::sIdentity(),
|
||||||
|
EMotionType::Dynamic,
|
||||||
|
Layers::MOVING);
|
||||||
|
settings.mLinearDamping = pbc.linear_damping;
|
||||||
|
settings.mAngularDamping = pbc.angular_damping;
|
||||||
|
settings.mGravityFactor = pbc.gravity_factor;
|
||||||
|
|
||||||
|
settings.mRestitution = psc->restitution;
|
||||||
|
settings.mFriction = psc->friction;
|
||||||
|
|
||||||
|
pbc.body = body_interface->CreateAndAddBody(settings, EActivation::Activate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::OnRuntimeStop()
|
||||||
|
{
|
||||||
|
auto view = registry.view<PhysicsBodyComponent>();
|
||||||
|
for (auto e : view) {
|
||||||
|
Entity entity = { e, this };
|
||||||
|
|
||||||
|
auto& pbc = entity.GetComponents<PhysicsBodyComponent>();
|
||||||
|
|
||||||
|
physics_engine.GetBodyInterface().RemoveBody(pbc.body);
|
||||||
|
physics_engine.GetBodyInterface().DestroyBody(pbc.body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Entity Scene::CreateEntity(const std::string& name)
|
Entity Scene::CreateEntity(const std::string& name)
|
||||||
{
|
{
|
||||||
Entity entity = { registry.create(), this };
|
Entity entity = { registry.create(), this };
|
||||||
@@ -37,6 +108,22 @@ namespace OpenEngine {
|
|||||||
pending_deletion.clear();
|
pending_deletion.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Scene::OnUpdatePhysics()
|
||||||
|
{
|
||||||
|
static int step = 0;
|
||||||
|
static float accumulator = 0.0f;
|
||||||
|
static const float fixedDT = 1.0f / 60.0f;
|
||||||
|
|
||||||
|
float real_delta_time = Time::DeltaTime(); // e.g. from a timer
|
||||||
|
accumulator += real_delta_time;
|
||||||
|
|
||||||
|
if (accumulator >= fixedDT) {
|
||||||
|
step++;
|
||||||
|
physics_engine.Update(fixedDT, 1);
|
||||||
|
accumulator -= fixedDT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Scene::OnUpdateRuntime()
|
void Scene::OnUpdateRuntime()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@@ -54,6 +141,40 @@ namespace OpenEngine {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto view = registry.view<TransformComponent, PhysicsBodyComponent>();
|
||||||
|
for (auto e : view) {
|
||||||
|
Entity entity = { e, this };
|
||||||
|
|
||||||
|
auto& pos = entity.GetComponents<TransformComponent>().translation;
|
||||||
|
auto& body = entity.GetComponents<PhysicsBodyComponent>();
|
||||||
|
|
||||||
|
body_interface->SetPosition(body.body, { pos.x, pos.y, pos.z }, EActivation::Activate);
|
||||||
|
|
||||||
|
PhysicsShapeComponent* shape;
|
||||||
|
if (entity.HasComponent<PhysicsShapeComponent>()) {
|
||||||
|
shape = &entity.GetComponents<PhysicsShapeComponent>();
|
||||||
|
|
||||||
|
body_interface->SetRestitution(body.body, shape->restitution);
|
||||||
|
body_interface->SetFriction(body.body, shape->friction);
|
||||||
|
body_interface->SetGravityFactor(body.body, body.gravity_factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
OnUpdatePhysics();
|
||||||
|
|
||||||
|
for (auto e : view) {
|
||||||
|
Entity entity = { e, this };
|
||||||
|
|
||||||
|
auto& transform = entity.GetComponents<TransformComponent>();
|
||||||
|
auto& body = entity.GetComponents<PhysicsBodyComponent>();
|
||||||
|
|
||||||
|
auto position = physics_engine.GetBodyInterface().GetPosition(body.body);
|
||||||
|
transform.translation.x = position.GetX();
|
||||||
|
transform.translation.y = position.GetY();
|
||||||
|
transform.translation.z = position.GetZ();
|
||||||
|
}
|
||||||
|
|
||||||
SceneCamera* main_camera = nullptr;
|
SceneCamera* main_camera = nullptr;
|
||||||
glm::mat4 main_transform{ 1.0f };
|
glm::mat4 main_transform{ 1.0f };
|
||||||
{
|
{
|
||||||
@@ -75,6 +196,7 @@ namespace OpenEngine {
|
|||||||
|
|
||||||
for (const auto& entity : view) {
|
for (const auto& entity : view) {
|
||||||
auto [transform, mesh] = view.get<TransformComponent, MeshComponent>(entity);
|
auto [transform, mesh] = view.get<TransformComponent, MeshComponent>(entity);
|
||||||
|
|
||||||
Material material;
|
Material material;
|
||||||
|
|
||||||
Entity _entity(entity, this);
|
Entity _entity(entity, this);
|
||||||
@@ -186,4 +308,14 @@ namespace OpenEngine {
|
|||||||
void Scene::OnComponentAdded<MaterialComponent>(Entity entity, MaterialComponent& component)
|
void Scene::OnComponentAdded<MaterialComponent>(Entity entity, MaterialComponent& component)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void Scene::OnComponentAdded<PhysicsBodyComponent>(Entity entity, PhysicsBodyComponent& component)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void Scene::OnComponentAdded<PhysicsShapeComponent>(Entity entity, PhysicsShapeComponent& component)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -274,19 +274,20 @@ namespace OpenEngine {
|
|||||||
if (mesh_component)
|
if (mesh_component)
|
||||||
{
|
{
|
||||||
auto& mesh = deserializedEntity.AddComponent<MeshComponent>();
|
auto& mesh = deserializedEntity.AddComponent<MeshComponent>();
|
||||||
|
mesh.primitive_type = (PrimitiveType)mesh_component["MeshType"].as<int>();
|
||||||
switch (mesh.primitive_type) {
|
switch (mesh.primitive_type) {
|
||||||
case OpenEngine::PrimitiveType::Quad:
|
case OpenEngine::PrimitiveType::Quad: {
|
||||||
{
|
|
||||||
mesh.mesh = CreateQuad((uint32_t)deserializedEntity);
|
mesh.mesh = CreateQuad((uint32_t)deserializedEntity);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OpenEngine::PrimitiveType::Cube:
|
case OpenEngine::PrimitiveType::Cube: {
|
||||||
{
|
|
||||||
mesh.mesh = CreateCube((uint32_t)deserializedEntity);
|
mesh.mesh = CreateCube((uint32_t)deserializedEntity);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default: {
|
||||||
break;
|
OE_CORE_ASSERT(false, "No mesh");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,9 +301,6 @@ namespace OpenEngine {
|
|||||||
material.material.ambient_strength = material_component["AmbiantStrength"].as<float>();
|
material.material.ambient_strength = material_component["AmbiantStrength"].as<float>();
|
||||||
material.material.specular_strength = material_component["SpecularStrength"].as<float>();
|
material.material.specular_strength = material_component["SpecularStrength"].as<float>();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto mesh = CreateCube((uint32_t)deserializedEntity);
|
|
||||||
deserializedEntity.AddComponent<MeshComponent>(mesh);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
Scene: N/A
|
|
||||||
Entities:
|
|
||||||
- Entity: 412741205
|
|
||||||
TagComponent:
|
|
||||||
Tag: square 3
|
|
||||||
TransformComponent:
|
|
||||||
Translation: [-1.49011612e-08, 0.299999774, -0.499999911]
|
|
||||||
Rotation: [-1.57079685, 0, 0]
|
|
||||||
Scale: [0.605000019, 0.60496217, 0.60496217]
|
|
||||||
SpriteRendererComponent:
|
|
||||||
Color: [1, 1, 1, 1]
|
|
||||||
- Entity: 412741205
|
|
||||||
TagComponent:
|
|
||||||
Tag: "square 2 "
|
|
||||||
TransformComponent:
|
|
||||||
Translation: [0, 0, -0.200000003]
|
|
||||||
Rotation: [0, 0, 0]
|
|
||||||
Scale: [0.600000024, 0.600000083, 0.600000024]
|
|
||||||
SpriteRendererComponent:
|
|
||||||
Color: [0.882352948, 0.745098054, 0.376470596, 1]
|
|
||||||
- Entity: 412741205
|
|
||||||
TagComponent:
|
|
||||||
Tag: square
|
|
||||||
TransformComponent:
|
|
||||||
Translation: [0.299827427, -9.68575478e-08, -0.499896437]
|
|
||||||
Rotation: [0, 1.57079637, 0]
|
|
||||||
Scale: [0.6049999, 0.604999959, 0.6049999]
|
|
||||||
SpriteRendererComponent:
|
|
||||||
Color: [0.517647088, 0.0901960805, 1, 1]
|
|
||||||
- Entity: 412741205
|
|
||||||
TagComponent:
|
|
||||||
Tag: camera
|
|
||||||
TransformComponent:
|
|
||||||
Translation: [0, 0, 20.8999996]
|
|
||||||
Rotation: [0, 0, 0]
|
|
||||||
Scale: [1, 1, 1]
|
|
||||||
CameraComponent:
|
|
||||||
Camera:
|
|
||||||
ProjectionType: 0
|
|
||||||
PerspectiveFOV: 45
|
|
||||||
PerspectiveNear: 0.00999999978
|
|
||||||
PerspectiveFar: 1000
|
|
||||||
OrthographicSize: 10
|
|
||||||
OrthographicNear: -1
|
|
||||||
OrthographicFar: 1
|
|
||||||
Primary: true
|
|
||||||
FixedAspectRatio: false
|
|
||||||
Reference in New Issue
Block a user