添加简单物理模拟模式功能
This commit is contained in:
@ -38,8 +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_IconPlay = Texture2D::Create("Resources/Icons/PlayButton.png");
|
||||
m_IconStop = Texture2D::Create("Resources/Icons/PauseButton.png");
|
||||
m_IconSimulate = Texture2D::Create("Resources/Icons/SimulateButton.png");
|
||||
|
||||
m_EditorScene = CreateRef<Scene>();
|
||||
m_EditorScene->OnViewportResize((uint32_t)m_ViewPortSize.x, (uint32_t)m_ViewPortSize.y);
|
||||
@ -94,6 +95,10 @@ namespace Hazel
|
||||
m_EditorCamera.OnUpdate(ts);
|
||||
m_ActiveScene->OnUpdateEditor(ts, m_EditorCamera);
|
||||
break;
|
||||
case SceneState::Simulate:
|
||||
m_EditorCamera.OnUpdate(ts);
|
||||
m_ActiveScene->OnUpdateSimulation(ts, m_EditorCamera);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@ -127,8 +132,12 @@ namespace Hazel
|
||||
|
||||
if (m_SceneState == SceneState::Play)
|
||||
{
|
||||
|
||||
Entity camera = m_ActiveScene->GetPrimaryCameraEntity();
|
||||
Renderer2D::BeginScene(camera.GetComponent<CameraComponent>().Camera, camera.GetComponent<TransformComponent>().GetTransform());
|
||||
if (camera)
|
||||
Renderer2D::BeginScene(camera.GetComponent<CameraComponent>().Camera, camera.GetComponent<TransformComponent>().GetTransform());
|
||||
else
|
||||
Renderer2D::BeginScene(m_EditorCamera);
|
||||
}else
|
||||
{
|
||||
Renderer2D::BeginScene(m_EditorCamera);
|
||||
@ -137,6 +146,46 @@ namespace Hazel
|
||||
if (m_ShowPhysicsColliders)
|
||||
{
|
||||
// box collider
|
||||
|
||||
auto bcview = m_ActiveScene->GetAllEntitiesWith<TransformComponent, BoxCollider2DComponent>();
|
||||
for (auto entity : bcview)
|
||||
{
|
||||
auto [tc, bc2D] = bcview.get<TransformComponent, BoxCollider2DComponent>(entity);
|
||||
|
||||
glm::vec3 scaledOffset = glm::vec3(
|
||||
bc2D.Offset.x * tc.Scale.x,
|
||||
bc2D.Offset.y * tc.Scale.y,
|
||||
0.0f
|
||||
);
|
||||
|
||||
glm::vec3 translation1 = tc.Translation + scaledOffset + glm::vec3(0.0f, 0.0f, 0.001f);
|
||||
|
||||
|
||||
// 创建完整的模型变换矩阵
|
||||
glm::mat4 model = glm::translate(glm::mat4(1.0f), translation1)
|
||||
* glm::rotate(glm::mat4(1.0f), tc.Rotation.z, glm::vec3(0.0f, 0.0f, 1.0f))
|
||||
* glm::scale(glm::mat4(1.0f), tc.Scale);
|
||||
|
||||
// 将 offset 从局部空间变换到世界空间
|
||||
glm::vec4 worldOffset = model * glm::vec4(bc2D.Offset.x, bc2D.Offset.y, 0.0f, 1.0f);
|
||||
|
||||
// 最终位置 = 实体位置 + 变换后的offset + Z偏移
|
||||
glm::vec3 translation = glm::vec3(worldOffset) + glm::vec3(0.0f, 0.0f, 0.001f);
|
||||
|
||||
// 计算缩放 (Size 是半宽半高,所以要乘2)
|
||||
glm::vec3 scale = tc.Scale * glm::vec3(bc2D.Size * 2.0f, 1.0f);
|
||||
|
||||
// 创建碰撞体变换矩阵 (包含旋转)
|
||||
glm::mat4 transform =
|
||||
glm::translate(glm::mat4(1.0f), translation)
|
||||
* glm::rotate(glm::mat4(1.0f), tc.Rotation.z, glm::vec3(0.0f, 0.0f, 1.0f))
|
||||
* glm::scale(glm::mat4(1.0f), scale);
|
||||
|
||||
Renderer2D::DrawRect(transform, glm::vec4(0.2f, 1.0f, 0.2f, 1.0f));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
auto bcview = m_ActiveScene->GetAllEntitiesWith<TransformComponent, BoxCollider2DComponent>();
|
||||
for (auto entity : bcview)
|
||||
{
|
||||
@ -149,6 +198,7 @@ namespace Hazel
|
||||
Renderer2D::DrawRect(transform, glm::vec4(0.2, 1.0f, 0.2f, 1.0f));
|
||||
}
|
||||
|
||||
*/
|
||||
// circle collider
|
||||
auto ccview = m_ActiveScene->GetAllEntitiesWith<TransformComponent, CircleCollider2DComponent>();
|
||||
for (auto entity : ccview)
|
||||
@ -357,7 +407,7 @@ namespace Hazel
|
||||
|
||||
cameraProjection = camera.GetProjection();
|
||||
cameraView = glm::inverse(cameraEntity.GetComponent<TransformComponent>().GetTransform());
|
||||
}else if (m_SceneState == SceneState::Edit)
|
||||
}else
|
||||
{
|
||||
cameraProjection = m_EditorCamera.GetProjection();
|
||||
cameraView = m_EditorCamera.GetViewMatrix();
|
||||
@ -477,6 +527,9 @@ namespace Hazel
|
||||
|
||||
void EditorLayer::OnScenePlay()
|
||||
{
|
||||
if (m_SceneState == SceneState::Simulate)
|
||||
OnSceneStop();
|
||||
|
||||
// SaveScene();
|
||||
m_SceneState = SceneState::Play;
|
||||
|
||||
@ -488,9 +541,31 @@ namespace Hazel
|
||||
|
||||
void EditorLayer::OnSceneStop()
|
||||
{
|
||||
if (m_SceneState != SceneState::Play && m_SceneState != SceneState::Simulate)
|
||||
{
|
||||
HZ_CORE_WARN("Scene is not playing or simulating!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_SceneState == SceneState::Play)
|
||||
m_ActiveScene->OnRuntimeStop();
|
||||
else if (m_SceneState == SceneState::Simulate)
|
||||
m_ActiveScene->OnSimulationStop();
|
||||
|
||||
m_SceneState = SceneState::Edit;
|
||||
m_ActiveScene->OnRuntimeStop();
|
||||
m_ActiveScene = m_EditorScene;
|
||||
m_SceneHierachyPanel.SetContext(m_ActiveScene);
|
||||
}
|
||||
|
||||
void EditorLayer::OnSceneSimulation()
|
||||
{
|
||||
if (m_SceneState == SceneState::Simulate)
|
||||
OnSceneStop();
|
||||
// SaveScene();
|
||||
m_SceneState = SceneState::Simulate;
|
||||
|
||||
m_ActiveScene = Scene::Copy(m_EditorScene);
|
||||
m_ActiveScene->OnSimulationStart();
|
||||
|
||||
m_SceneHierachyPanel.SetContext(m_ActiveScene);
|
||||
}
|
||||
@ -583,18 +658,30 @@ namespace Hazel
|
||||
// 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}))
|
||||
|
||||
Ref<Texture2D> icon = (m_SceneState == SceneState::Edit || m_SceneState == SceneState::Simulate)? m_IconPlay : m_IconStop;
|
||||
if (ImGui::ImageButton("toolbar-play-edit", icon->GetRendererID(), ImVec2{size, size}, ImVec2{0, 0}, ImVec2{1, 1}))
|
||||
{
|
||||
if (m_SceneState == SceneState::Edit)
|
||||
if (m_SceneState == SceneState::Edit || m_SceneState == SceneState::Simulate)
|
||||
OnScenePlay();
|
||||
else if (m_SceneState == SceneState::Play)
|
||||
OnSceneStop();
|
||||
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
{
|
||||
Ref<Texture2D> icon = (m_SceneState == SceneState::Edit || m_SceneState == SceneState::Play)? m_IconSimulate : m_IconStop;
|
||||
if (ImGui::ImageButton("toolbar-simulate", icon->GetRendererID(), ImVec2{size, size}, ImVec2{0, 0}, ImVec2{1, 1}))
|
||||
{
|
||||
if (m_SceneState == SceneState::Edit || m_SceneState == SceneState::Play)
|
||||
OnSceneSimulation();
|
||||
else if (m_SceneState == SceneState::Simulate)
|
||||
OnSceneStop();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PopStyleVar(2);
|
||||
ImGui::PopStyleColor(3);
|
||||
ImGui::End();
|
||||
|
||||
Reference in New Issue
Block a user