添加box2d库
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -23,3 +23,6 @@
|
||||
[submodule "Hazel/vendor/SPIRV-Cross"]
|
||||
path = Hazel/vendor/SPIRV-Cross
|
||||
url = https://github.com/KhronosGroup/SPIRV-Cross.git
|
||||
[submodule "Hazel/vendor/box2d"]
|
||||
path = Hazel/vendor/box2d
|
||||
url = https://github.com/erincatto/box2d.git
|
||||
|
||||
@ -8,6 +8,7 @@ add_subdirectory(vendor/glm)
|
||||
add_subdirectory(vendor/yaml-cpp)
|
||||
add_subdirectory(vendor/shaderc)
|
||||
add_subdirectory(vendor/SPIRV-Cross)
|
||||
add_subdirectory(vendor/box2d)
|
||||
|
||||
file(GLOB_RECURSE SOURCES "src/**.cpp")
|
||||
|
||||
@ -64,6 +65,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||
shaderc
|
||||
spirv-cross-cpp
|
||||
spirv-cross-core
|
||||
box2d
|
||||
)
|
||||
# target_compile_definitions(${PROJECT_NAME} PRIVATE HZ_BUILD_DLL IMGUI_API=__declspec\(dllexport\) STB_IMAGE_IMPLEMENTATION)# 编译DLL时定义
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE STB_IMAGE_IMPLEMENTATION)
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
|
||||
struct TransformComponent
|
||||
{
|
||||
glm::vec3 Translation{0.0f};
|
||||
@ -91,6 +92,41 @@ namespace Hazel
|
||||
DestroyScript = [](NativeScriptComponent* nsc) { delete nsc->Instance; nsc->Instance = nullptr; };
|
||||
}
|
||||
};
|
||||
|
||||
// Physics
|
||||
|
||||
struct RigidBody2DComponent
|
||||
{
|
||||
enum class BodyType { Static = 0, Dynamic, Kinematic };
|
||||
|
||||
BodyType Type = BodyType::Static;
|
||||
bool FixedRotation = false;
|
||||
|
||||
// Storage for runtime
|
||||
b2BodyId RuntimeBody;
|
||||
|
||||
RigidBody2DComponent() = default;
|
||||
RigidBody2DComponent(const RigidBody2DComponent&) = default;
|
||||
};
|
||||
|
||||
struct BoxCollider2DComponent
|
||||
{
|
||||
glm::vec2 Offset = {0.0f, 0.0f};
|
||||
glm::vec2 Size = {0.5f, 0.5f};
|
||||
|
||||
// TODO(Yan): move into material texture in the future
|
||||
float Density = 1.0f; // 密度
|
||||
float Friction = 0.5f; // 摩擦力
|
||||
float Restitution = 0.0f; // 弹力
|
||||
float RestitutionThreshold = 0.5f; // 弹力阈值
|
||||
|
||||
// Storage for runtime
|
||||
void *RuntimeBody = nullptr;
|
||||
|
||||
BoxCollider2DComponent() = default;
|
||||
BoxCollider2DComponent(const BoxCollider2DComponent&) = default;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -9,9 +9,26 @@
|
||||
#include "Components.h"
|
||||
|
||||
#include "Entity.h"
|
||||
#include "../../../vendor/box2d/src/physics_world.h"
|
||||
#include "box2d/box2d.h"
|
||||
#include "box2d/id.h"
|
||||
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
static b2BodyType RigidBodyTypeToBox2DBodyType(RigidBody2DComponent::BodyType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case RigidBody2DComponent::BodyType::Static: return b2_staticBody;
|
||||
case RigidBody2DComponent::BodyType::Dynamic: return b2_dynamicBody;
|
||||
case RigidBody2DComponent::BodyType::Kinematic: return b2_kinematicBody;
|
||||
}
|
||||
|
||||
HZ_CORE_ERROR("Unknown body type");
|
||||
return b2_staticBody;
|
||||
}
|
||||
|
||||
Scene::Scene()
|
||||
{
|
||||
}
|
||||
@ -34,6 +51,57 @@ namespace Hazel
|
||||
m_Registry.destroy(entity);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Scene::OnRuntimeStart()
|
||||
{
|
||||
b2WorldDef worldDef = b2DefaultWorldDef();
|
||||
worldDef.gravity = b2Vec2(0.0f, -9.81f);
|
||||
m_PhysicsWorld = b2CreateWorld( &worldDef );
|
||||
|
||||
auto view = m_Registry.view<RigidBody2DComponent>();
|
||||
for (auto e : view)
|
||||
{
|
||||
Entity entity = {e, this};
|
||||
auto &transform = entity.GetComponent<TransformComponent>();
|
||||
auto &rb2D = entity.GetComponent<RigidBody2DComponent>();
|
||||
|
||||
b2BodyDef bodyDef = b2DefaultBodyDef();
|
||||
bodyDef.type = RigidBodyTypeToBox2DBodyType(rb2D.Type);
|
||||
bodyDef.position = {transform.Translation.x, transform.Translation.y};
|
||||
float angle = transform.Rotation.z;
|
||||
bodyDef.rotation = b2Rot{cos(angle), sin(angle)};
|
||||
|
||||
// bodyDef.fixedRotation = true;
|
||||
|
||||
b2BodyId body = b2CreateBody(m_PhysicsWorld, &bodyDef);
|
||||
|
||||
rb2D.RuntimeBody = body;
|
||||
if (entity.HasComponent<BoxCollider2DComponent>())
|
||||
{
|
||||
auto& bc2d = entity.GetComponent<BoxCollider2DComponent>();
|
||||
|
||||
float hx = bc2d.Size.x * transform.Scale.x;
|
||||
float hy = bc2d.Size.y * transform.Scale.y;
|
||||
b2Polygon boxShape = b2MakeBox(hx, hy);
|
||||
b2ShapeDef shapedef = b2DefaultShapeDef();
|
||||
|
||||
shapedef.density = bc2d.Density;
|
||||
shapedef.material.friction = bc2d.Friction;
|
||||
shapedef.material.restitution = bc2d.Restitution;
|
||||
|
||||
b2CreatePolygonShape(body, &shapedef,&boxShape);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::OnRuntimeStop()
|
||||
{
|
||||
|
||||
b2DestroyWorld( m_PhysicsWorld );
|
||||
}
|
||||
|
||||
void Scene::OnUpdateRuntime(TimeStep& ts)
|
||||
{
|
||||
|
||||
@ -54,6 +122,30 @@ namespace Hazel
|
||||
});
|
||||
}
|
||||
|
||||
// Physics
|
||||
{
|
||||
const int32_t velocityIteration = 6;
|
||||
const int32_t positionIteration = 2;
|
||||
|
||||
b2World_Step(m_PhysicsWorld, ts, 4);
|
||||
|
||||
auto view = m_Registry.view<RigidBody2DComponent>();
|
||||
for (auto e : view)
|
||||
{
|
||||
Entity entity = {e, this};
|
||||
auto& transform = entity.GetComponent<TransformComponent>();
|
||||
auto& rb2D = entity.GetComponent<RigidBody2DComponent>();
|
||||
|
||||
b2BodyId &body = rb2D.RuntimeBody;
|
||||
|
||||
const auto& position = b2Body_GetPosition(body);
|
||||
transform.Translation.x = position.x;
|
||||
transform.Translation.y = position.y;
|
||||
const float angle = b2Rot_GetAngle(b2Body_GetRotation(body));
|
||||
transform.Rotation.z = angle;
|
||||
}
|
||||
}
|
||||
|
||||
// Renderer 2D
|
||||
Camera* mainCamera = nullptr;
|
||||
glm::mat4 cameraTranform;
|
||||
@ -82,7 +174,7 @@ namespace Hazel
|
||||
{
|
||||
auto [transform, sprite] = group.get<TransformComponent, SpriteRendererComponent>(entity);
|
||||
|
||||
Renderer2D::DrawQuad(transform.GetTransform(), sprite.Color);
|
||||
Renderer2D::DrawSprite(transform.GetTransform(), sprite, (int)entity);
|
||||
}
|
||||
|
||||
Renderer2D::EndScene();
|
||||
@ -169,10 +261,22 @@ namespace Hazel
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
void Scene::OnComponentAdded<RigidBody2DComponent>(Entity entity, RigidBody2DComponent& component)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
void Scene::OnComponentAdded<BoxCollider2DComponent>(Entity entity, BoxCollider2DComponent& component)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
template HAZEL_API void Scene::OnComponentAdded<TransformComponent>(Entity, TransformComponent&);
|
||||
template HAZEL_API void Scene::OnComponentAdded<CameraComponent>(Entity, CameraComponent&);
|
||||
template HAZEL_API void Scene::OnComponentAdded<TagComponent>(Entity, TagComponent&);
|
||||
template HAZEL_API void Scene::OnComponentAdded<SpriteRendererComponent>(Entity, SpriteRendererComponent&);
|
||||
template HAZEL_API void Scene::OnComponentAdded<NativeScriptComponent>(Entity, NativeScriptComponent&);
|
||||
template HAZEL_API void Scene::OnComponentAdded<RigidBody2DComponent>(Entity, RigidBody2DComponent&);
|
||||
template HAZEL_API void Scene::OnComponentAdded<BoxCollider2DComponent>(Entity, BoxCollider2DComponent&);
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#define SCENE_H
|
||||
|
||||
|
||||
#include <box2d/id.h>
|
||||
#include <Hazel/Core/TimeStep.h>
|
||||
#include <Hazel/Renderer/EditorCamera.h>
|
||||
|
||||
@ -13,7 +14,6 @@
|
||||
#include "Hazel/Core/Core.h"
|
||||
|
||||
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
class Entity;
|
||||
@ -27,10 +27,11 @@ namespace Hazel
|
||||
|
||||
void DestoryEntity(Entity entity);
|
||||
|
||||
void OnRuntimeStart();
|
||||
void OnRuntimeStop();
|
||||
|
||||
void OnUpdateRuntime(TimeStep& ts);
|
||||
|
||||
void OnUpdateEditor(TimeStep& ts, const EditorCamera& camera);
|
||||
|
||||
void OnViewportResize(uint32_t width, uint32_t height);
|
||||
|
||||
Entity GetPrimaryCameraEntity();
|
||||
@ -43,6 +44,8 @@ namespace Hazel
|
||||
entt::registry m_Registry;
|
||||
uint32_t m_ViewportWidth = 0, m_ViewportHeight = 0;
|
||||
|
||||
b2WorldId m_PhysicsWorld;
|
||||
|
||||
friend class Entity;
|
||||
friend class SceneSerializer;
|
||||
friend class SceneHierachyPanel;
|
||||
|
||||
@ -12,6 +12,28 @@
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
template<>
|
||||
struct convert<glm::vec2>
|
||||
{
|
||||
static Node encode(const glm::vec2& out)
|
||||
{
|
||||
Node node;
|
||||
node.push_back(out.x);
|
||||
node.push_back(out.y);
|
||||
node.SetStyle(EmitterStyle::Flow);
|
||||
return node;
|
||||
}
|
||||
|
||||
static bool decode(const Node& node, glm::vec2& out)
|
||||
{
|
||||
if (node.size() != 2 && !node.IsSequence())
|
||||
return false;
|
||||
out.x = node[0].as<float>();
|
||||
out.y = node[1].as<float>();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct convert<glm::vec3>
|
||||
{
|
||||
@ -62,6 +84,34 @@ namespace YAML
|
||||
}
|
||||
};
|
||||
|
||||
static std::string RigidBody2DTypeToString(Hazel::RigidBody2DComponent::BodyType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Hazel::RigidBody2DComponent::BodyType::Static: return "Static";
|
||||
case Hazel::RigidBody2DComponent::BodyType::Dynamic: return "Dynamic";
|
||||
case Hazel::RigidBody2DComponent::BodyType::Kinematic: return "Kinematic";
|
||||
}
|
||||
HZ_CORE_ERROR("Unknown body type!");
|
||||
return {};
|
||||
}
|
||||
|
||||
static Hazel::RigidBody2DComponent::BodyType RigidBody2DStringToType(const std::string& type)
|
||||
{
|
||||
if (type == "Static") return Hazel::RigidBody2DComponent::BodyType::Static;
|
||||
if (type == "Dynamic") return Hazel::RigidBody2DComponent::BodyType::Dynamic;
|
||||
if (type == "Kinematic") return Hazel::RigidBody2DComponent::BodyType::Kinematic;
|
||||
HZ_CORE_ERROR("Unknown body type!");
|
||||
return Hazel::RigidBody2DComponent::BodyType::Static;
|
||||
}
|
||||
|
||||
Emitter& operator<<(Emitter& out, const glm::vec2& value)
|
||||
{
|
||||
out << Flow;
|
||||
out << BeginSeq << value.x << value.y << EndSeq;
|
||||
return out;
|
||||
}
|
||||
|
||||
Emitter& operator<<(Emitter& out, const glm::vec3& value)
|
||||
{
|
||||
out << Flow;
|
||||
@ -154,6 +204,33 @@ namespace Hazel
|
||||
out << YAML::EndMap; // SpriteRendererComponent
|
||||
}
|
||||
|
||||
if (entity.HasComponent<RigidBody2DComponent>())
|
||||
{
|
||||
out << YAML::Key << "RigidBody2DComponent";
|
||||
|
||||
out << YAML::BeginMap; // RigidBody2DComponent
|
||||
auto& rb2dComponent = entity.GetComponent<RigidBody2DComponent>();
|
||||
out << YAML::Key << "BodyType" << YAML::Value << YAML::RigidBody2DTypeToString(rb2dComponent.Type);
|
||||
out << YAML::Key << "FixedRotation" << YAML::Value << rb2dComponent.FixedRotation;
|
||||
out << YAML::EndMap; // RigidBody2DComponent
|
||||
}
|
||||
|
||||
if (entity.HasComponent<BoxCollider2DComponent>())
|
||||
{
|
||||
out << YAML::Key << "BoxCollider2DComponent";
|
||||
|
||||
out << YAML::BeginMap; // BoxCollider2DComponent
|
||||
auto& bc2dComponent = entity.GetComponent<BoxCollider2DComponent>();
|
||||
out << YAML::Key << "Offset" << YAML::Value << bc2dComponent.Offset;
|
||||
out << YAML::Key << "Size" << YAML::Value << bc2dComponent.Size;
|
||||
out << YAML::Key << "Density" << YAML::Value << bc2dComponent.Density;
|
||||
out << YAML::Key << "Friction" << YAML::Value << bc2dComponent.Friction;
|
||||
out << YAML::Key << "Restitution" << YAML::Value << bc2dComponent.Restitution;
|
||||
out << YAML::Key << "Restitution" << YAML::Value << bc2dComponent.Restitution;
|
||||
out << YAML::Key << "RestitutionThreshold" << YAML::Value << bc2dComponent.RestitutionThreshold;
|
||||
out << YAML::EndMap; // BoxCollider2DComponent
|
||||
}
|
||||
|
||||
out << YAML::EndMap; // entity
|
||||
}
|
||||
|
||||
@ -250,6 +327,26 @@ namespace Hazel
|
||||
sprite.Color = spriteRendererComponent["Color"].as<glm::vec4>();
|
||||
}
|
||||
|
||||
auto rigidBody2DComponent = entity["RigidBody2DComponent"];
|
||||
if (rigidBody2DComponent)
|
||||
{
|
||||
auto& rb2d = deserializedEntity.AddComponent<RigidBody2DComponent>();
|
||||
rb2d.Type = YAML::RigidBody2DStringToType(rigidBody2DComponent["BodyType"].as<std::string>());
|
||||
rb2d.FixedRotation = rigidBody2DComponent["FixedRotation"].as<bool>();
|
||||
}
|
||||
|
||||
auto boxCollider2DComponent = entity["BoxCollider2DComponent"];
|
||||
if (boxCollider2DComponent)
|
||||
{
|
||||
auto& bc2d = deserializedEntity.AddComponent<BoxCollider2DComponent>();
|
||||
bc2d.Offset = boxCollider2DComponent["Offset"].as<glm::vec2>();
|
||||
bc2d.Size = boxCollider2DComponent["Size"].as<glm::vec2>();
|
||||
bc2d.Density = boxCollider2DComponent["Density"].as<float>();
|
||||
bc2d.Friction = boxCollider2DComponent["Friction"].as<float>();
|
||||
bc2d.Restitution = boxCollider2DComponent["Restitution"].as<float>();
|
||||
bc2d.RestitutionThreshold = boxCollider2DComponent["RestitutionThreshold"].as<float>();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
1
Hazel/vendor/box2d
vendored
Submodule
1
Hazel/vendor/box2d
vendored
Submodule
Submodule Hazel/vendor/box2d added at fcc60b76e1
@ -38,6 +38,9 @@ namespace Hazel
|
||||
m_LogoTexture = Texture2D::Create("assets/textures/iceLogo.png");
|
||||
m_CheckerBoardTexture = Texture2D::Create("assets/textures/Checkerboard.png");
|
||||
|
||||
m_PlayIcon = Texture2D::Create("Resources/Icons/PlayButton.png");
|
||||
m_StopIcon = Texture2D::Create("Resources/Icons/PauseButton.png");
|
||||
|
||||
m_ActiveScene = CreateRef<Scene>();
|
||||
|
||||
m_EditorCamera = EditorCamera(45.0f, 1.667f, 0.1f, 1000.0f);
|
||||
@ -66,11 +69,6 @@ namespace Hazel
|
||||
}
|
||||
|
||||
// update camera
|
||||
if (m_ViewportFocused)
|
||||
{
|
||||
m_CameraController.OnUpdate(ts);
|
||||
m_EditorCamera.OnUpdate(ts);
|
||||
}
|
||||
|
||||
// update Renderer
|
||||
m_FrameBuffer->Bind();
|
||||
@ -79,10 +77,21 @@ namespace Hazel
|
||||
|
||||
m_FrameBuffer->ClearAttachment(1, -1);
|
||||
|
||||
// Renderer2D::BeginScene(m_CameraController.GetCamera());
|
||||
switch (m_SceneState)
|
||||
{
|
||||
case SceneState::Play:
|
||||
m_ActiveScene->OnUpdateRuntime(ts);
|
||||
break;
|
||||
case SceneState::Edit:
|
||||
if (m_ViewportFocused)
|
||||
m_CameraController.OnUpdate(ts);
|
||||
|
||||
// update Scene
|
||||
m_ActiveScene->OnUpdateEditor(ts, m_EditorCamera);
|
||||
m_EditorCamera.OnUpdate(ts);
|
||||
m_ActiveScene->OnUpdateEditor(ts, m_EditorCamera);
|
||||
break;
|
||||
}
|
||||
|
||||
// Renderer2D::BeginScene(m_CameraController.GetCamera());
|
||||
|
||||
auto [mx, my] = ImGui::GetMousePos();
|
||||
mx -= m_ViewPortBounds[0].x;
|
||||
@ -275,17 +284,27 @@ namespace Hazel
|
||||
|
||||
ImGuizmo::SetRect(windowPos.x, windowPos.y, windowWidth, windowHeight);
|
||||
|
||||
// auto cameraEntity = m_ActiveScene->GetPrimaryCameraEntity();
|
||||
if (m_GizmoType != -1)
|
||||
{
|
||||
// const auto& camera = cameraEntity.GetComponent<CameraComponent>().Camera;
|
||||
|
||||
glm::mat4 cameraProjection;
|
||||
glm::mat4 cameraView;
|
||||
|
||||
if (m_SceneState == SceneState::Play)
|
||||
{
|
||||
auto cameraEntity = m_ActiveScene->GetPrimaryCameraEntity();
|
||||
const auto& camera = cameraEntity.GetComponent<CameraComponent>().Camera;
|
||||
|
||||
cameraProjection = camera.GetProjection();
|
||||
cameraView = glm::inverse(cameraEntity.GetComponent<TransformComponent>().GetTransform());
|
||||
}else if (m_SceneState == SceneState::Edit)
|
||||
{
|
||||
cameraProjection = m_EditorCamera.GetProjection();
|
||||
cameraView = m_EditorCamera.GetViewMatrix();
|
||||
}
|
||||
|
||||
auto& tc = selectedEntity.GetComponent<TransformComponent>();
|
||||
|
||||
|
||||
// const glm::mat4& cameraProjection = camera.GetProjection();
|
||||
// glm::mat4 cameraView = glm::inverse(cameraEntity.GetComponent<TransformComponent>().GetTransform());
|
||||
glm::mat4 cameraProjection = m_EditorCamera.GetProjection();
|
||||
glm::mat4 cameraView = m_EditorCamera.GetViewMatrix();
|
||||
glm::mat4 transform = tc.GetTransform();
|
||||
bool snap = SDL_GetModState() & SDL_KMOD_CTRL;
|
||||
float snapValue = 0.5f;
|
||||
@ -298,7 +317,7 @@ namespace Hazel
|
||||
|
||||
float snapValues[3] = {snapValue, snapValue, snapValue};
|
||||
if (ImGuizmo::Manipulate(glm::value_ptr(cameraView), glm::value_ptr(cameraProjection),
|
||||
ImGuizmo::OPERATION(m_GizmoType), ImGuizmo::LOCAL,
|
||||
static_cast<ImGuizmo::OPERATION>(m_GizmoType), ImGuizmo::WORLD,
|
||||
glm::value_ptr(transform), nullptr, snap ? snapValues : nullptr) && !Input::IsKeyPressed(SDL_SCANCODE_LALT))
|
||||
{
|
||||
if (ImGuizmo::IsUsing())
|
||||
@ -321,6 +340,9 @@ namespace Hazel
|
||||
ImGui::End();
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
|
||||
UI_ToolBar();
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
}
|
||||
@ -417,4 +439,51 @@ namespace Hazel
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void EditorLayer::UI_ToolBar()
|
||||
{
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 2));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing, ImVec2(0, 0));
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
|
||||
auto& colors = ImGui::GetStyle().Colors;
|
||||
auto& buttonHovered = colors[ImGuiCol_ButtonHovered];
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(buttonHovered.x, buttonHovered.y, buttonHovered.z, 0.5f));
|
||||
auto& buttonActive = colors[ImGuiCol_ButtonActive];
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(buttonActive.x, buttonActive.y, buttonActive.z, 0.5f));
|
||||
|
||||
|
||||
ImGui::Begin("##ToolBar", nullptr, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
|
||||
// ImGui::Begin("##ToolBar", nullptr);
|
||||
|
||||
float size = ImGui::GetWindowHeight() - 10.0f;
|
||||
Ref<Texture2D> icon = m_SceneState == SceneState::Edit ? m_PlayIcon : m_StopIcon;
|
||||
ImGui::SetCursorPosX(ImGui::GetWindowContentRegionMax().x * 0.5f - size * 0.5f);
|
||||
ImGui::SetCursorPosX(ImGui::GetWindowContentRegionMax().x * 0.5f - (size * 0.5f));
|
||||
if (ImGui::ImageButton("toolbar", icon->GetRendererID(), ImVec2{size, size}, ImVec2{0, 0}, ImVec2{1, 1}))
|
||||
{
|
||||
if (m_SceneState == SceneState::Edit)
|
||||
OnScenePlay();
|
||||
else if (m_SceneState == SceneState::Play)
|
||||
OnSceneStop();
|
||||
|
||||
}
|
||||
|
||||
|
||||
ImGui::PopStyleVar(2);
|
||||
ImGui::PopStyleColor(3);
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void EditorLayer::OnScenePlay()
|
||||
{
|
||||
m_SceneState = SceneState::Play;
|
||||
m_ActiveScene->OnRuntimeStart();
|
||||
}
|
||||
|
||||
void EditorLayer::OnSceneStop()
|
||||
{
|
||||
m_SceneState = SceneState::Edit;
|
||||
m_ActiveScene->OnRuntimeStop();
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,18 +24,25 @@ namespace Hazel
|
||||
virtual void OnImGuiRender() override;
|
||||
virtual void OnEvent(SDL_Event& e) override;
|
||||
private:
|
||||
void UI_ToolBar();
|
||||
|
||||
void OnScenePlay();
|
||||
void OnSceneStop();
|
||||
|
||||
void SaveScene() const;
|
||||
void OpenScene();
|
||||
void OpenScene(const std::filesystem::path& scenePath);
|
||||
void NewScene();
|
||||
|
||||
void ChangeOptMode(unsigned int mode);
|
||||
|
||||
private:
|
||||
OrthographicCameraController m_CameraController;
|
||||
|
||||
Ref<Texture2D> m_LogoTexture;
|
||||
Ref<Texture2D> m_CheckerBoardTexture;
|
||||
|
||||
|
||||
Ref<Scene> m_ActiveScene;
|
||||
EditorCamera m_EditorCamera;
|
||||
|
||||
@ -53,7 +60,16 @@ namespace Hazel
|
||||
SceneHierachyPanel m_SceneHierachyPanel;
|
||||
ContentBroswerPanel m_ContentBroswerPanel;
|
||||
|
||||
int m_GizmoType = 0;
|
||||
int m_GizmoType = -1;
|
||||
|
||||
enum class SceneState
|
||||
{
|
||||
Edit = 0, Play = 1
|
||||
};
|
||||
|
||||
SceneState m_SceneState = SceneState::Edit;
|
||||
|
||||
Ref<Texture2D> m_PlayIcon, m_StopIcon;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -251,15 +251,40 @@ namespace Hazel
|
||||
ImGui::OpenPopup("Add");
|
||||
if (ImGui::BeginPopup("Add"))
|
||||
{
|
||||
if (ImGui::MenuItem("Camera"))
|
||||
if (!m_SelectionContext.HasComponent<CameraComponent>())
|
||||
{
|
||||
m_SelectionContext.AddComponent<CameraComponent>();
|
||||
ImGui::CloseCurrentPopup();
|
||||
if (ImGui::MenuItem("Camera"))
|
||||
{
|
||||
m_SelectionContext.AddComponent<CameraComponent>();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
if (ImGui::MenuItem("Sprite"))
|
||||
|
||||
if (!m_SelectionContext.HasComponent<SpriteRendererComponent>())
|
||||
{
|
||||
m_SelectionContext.AddComponent<SpriteRendererComponent>();
|
||||
ImGui::CloseCurrentPopup();
|
||||
if (ImGui::MenuItem("Sprite"))
|
||||
{
|
||||
m_SelectionContext.AddComponent<SpriteRendererComponent>();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_SelectionContext.HasComponent<RigidBody2DComponent>())
|
||||
{
|
||||
if (ImGui::MenuItem("RigidBody 2D"))
|
||||
{
|
||||
m_SelectionContext.AddComponent<RigidBody2DComponent>();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_SelectionContext.HasComponent<BoxCollider2DComponent>())
|
||||
{
|
||||
if (ImGui::MenuItem("Box Collider 2D"))
|
||||
{
|
||||
m_SelectionContext.AddComponent<BoxCollider2DComponent>();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
@ -356,8 +381,48 @@ namespace Hazel
|
||||
|
||||
ImGui::DragFloat("Tiling Color", &component.TilingFactor, 0.1f, 0.0f, 100.f);
|
||||
});
|
||||
|
||||
|
||||
DrawComponent<RigidBody2DComponent>("Rigidbody 2D", entity, [](auto& component)
|
||||
{
|
||||
static const char* bodyTypeStrings[] = {"Static", "Dynamic", "Kinematic"};
|
||||
|
||||
const char* currentBodyTypeString = bodyTypeStrings[(int)component.Type];
|
||||
if (ImGui::BeginCombo("Body Type", currentBodyTypeString))
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
const bool isSelected = currentBodyTypeString == bodyTypeStrings[i];
|
||||
if (ImGui::Selectable(bodyTypeStrings[i], isSelected))
|
||||
{
|
||||
currentBodyTypeString = bodyTypeStrings[i];
|
||||
component.Type = (RigidBody2DComponent::BodyType)i;
|
||||
}
|
||||
|
||||
if (isSelected)
|
||||
{
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
ImGui::Checkbox("Fixed Rotation", &component.FixedRotation);
|
||||
});
|
||||
|
||||
DrawComponent<BoxCollider2DComponent>("Box Collider 2D", entity, [](auto& component)
|
||||
{
|
||||
ImGui::DragFloat2("Offset", glm::value_ptr(component.Offset));
|
||||
ImGui::DragFloat2("Size", glm::value_ptr(component.Size));
|
||||
|
||||
ImGui::DragFloat("Density", &component.Density, 0.01f, 0.0f);
|
||||
ImGui::DragFloat("Friction", &component.Friction, 0.01f, 0.0f, 1.0f);
|
||||
ImGui::DragFloat("Restitution", &component.Restitution, 0.01f, 0.0f, 1.0f);
|
||||
ImGui::DragFloat("Restitution Threshold", &component.RestitutionThreshold, 0.01f, 0.0f);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void SceneHierachyPanel::SetSelectedEntity(const Entity entity)
|
||||
{
|
||||
m_SelectionContext = entity;
|
||||
|
||||
@ -10,7 +10,7 @@ namespace Hazel
|
||||
{
|
||||
public:
|
||||
HazelEditor()
|
||||
: Application("Hazel Editor", 1600, 900)
|
||||
: Application("Hazel Editor", 1920, 1080)
|
||||
{
|
||||
PushLayer(new EditorLayer());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user