add support for joystick; move some mono dlls to new path

This commit is contained in:
2026-04-25 21:57:52 +08:00
parent 971f16d526
commit 79707b77f5
197 changed files with 1165 additions and 26 deletions

View File

@ -268,7 +268,6 @@ namespace Prism
if (ImGui::BeginMenu("Edit")) if (ImGui::BeginMenu("Edit"))
{ {
ImGui::MenuItem("Physics Settings", nullptr, &m_ShowPhysicsSettings); ImGui::MenuItem("Physics Settings", nullptr, &m_ShowPhysicsSettings);
ImGui::EndMenu(); ImGui::EndMenu();
} }
@ -284,6 +283,9 @@ namespace Prism
Physics3D::DisconnectPVD(); Physics3D::DisconnectPVD();
} }
ImGui::Separator();
ImGui::MenuItem("GamePad View", nullptr, &m_ShowGamePadSettings);
ImGui::EndMenu(); ImGui::EndMenu();
} }
@ -572,6 +574,9 @@ namespace Prism
// m_EditorCamera.OnImGuiRender(); // m_EditorCamera.OnImGuiRender();
m_ConsolePanel->OnImGuiRender(); m_ConsolePanel->OnImGuiRender();
// GamePad
DrawGamepadDebugPanel(m_ShowGamePadSettings);
// Editor Panel ------------------------------------------------------------------------------ // Editor Panel ------------------------------------------------------------------------------
ImGui::Begin("Environment"); ImGui::Begin("Environment");
{ {
@ -1175,6 +1180,249 @@ namespace Prism
Application::Get().GetWindow().SetTitle(title); Application::Get().GetWindow().SetTitle(title);
} }
void EditorLayer::DrawGamepadDebugPanel(bool& p_open)
{
if (!p_open)
return;
ImGui::Begin("Gamepad Debug", &p_open);
ImDrawList* drawList = ImGui::GetWindowDrawList();
bool anyConnected = false;
for (int jid = 0; jid <= 15; ++jid)
{
if (!Input::IsGamepadConnected(jid))
continue;
anyConnected = true;
const char* name = Input::GetGamepadName(jid);
bool isGamepad = Input::IsGamepad(jid);
// 使用 CollapsingHeader 或 TreeNodeEx 均可,这里用 TreeNodeEx 保持与之前类似
if (ImGui::TreeNodeEx((void*)(intptr_t)jid, ImGuiTreeNodeFlags_DefaultOpen,
"Joystick %d: %s%s", jid, name, isGamepad ? " (mapped)" : ""))
{
// ---------- 1. 摇杆与主要按钮行 ----------
const float stickRadius = 40.0f; // 圆形摇杆半径
const ImVec2 stickSize(stickRadius * 2, stickRadius * 2);
const float buttonSize = 30.0f; // 普通按钮ABXY的大小
const float dpadButtonSize = 30.0f; // 十字键按钮稍小
// 左摇杆区域
auto drawStick = [&](const char* label, float x, float y)
{
// 注意GLFW 左 Y 向上为负,右 Y 向上为负,统一取反
y = -y;
ImGui::BeginGroup();
ImGui::Text("%s", label);
const ImVec2 pos = ImGui::GetCursorScreenPos();
const ImVec2 center(pos.x + stickRadius, pos.y + stickRadius);
// 圆形底板
drawList->AddCircleFilled(center, stickRadius, IM_COL32(30,30,30,255));
drawList->AddCircle(center, stickRadius, IM_COL32(100,100,100,255), 0, 2.0f);
// 十字参考线
drawList->AddLine(ImVec2(center.x - stickRadius, center.y), ImVec2(center.x + stickRadius, center.y), IM_COL32(70,70,70,255));
drawList->AddLine(ImVec2(center.x, center.y - stickRadius), ImVec2(center.x, center.y + stickRadius), IM_COL32(70,70,70,255));
// 摇杆位置点
const float len = sqrtf(x*x + y*y);
float clampX = x, clampY = y;
if (len > 1.0f) { clampX /= len; clampY /= len; }
const float dotX = center.x + clampX * stickRadius;
const float dotY = center.y - clampY * stickRadius; // 屏幕Y向下故用减
drawList->AddCircleFilled(ImVec2(dotX, dotY), 6.0f, IM_COL32(255,80,80,255));
if (len > 0.99f)
drawList->AddCircle(center, stickRadius, IM_COL32(255,255,0,150), 0, 3.0f);
ImGui::Dummy(stickSize);
ImGui::EndGroup();
};
// 十字键(上下左右)
auto drawDPad = [&]()
{
ImGui::BeginGroup();
ImGui::Text("DPad");
ImVec2 base = ImGui::GetCursorScreenPos();
// 上
bool up = Prism::Input::IsGamepadButtonPressed(jid, Prism::GamepadButton::DPAD_UP);
ImGui::SetCursorScreenPos(ImVec2(base.x + dpadButtonSize, base.y));
ImGui::PushStyleColor(ImGuiCol_Button, up ? ImVec4(0.0f,1.0f,0.0f,1.0f) : ImVec4(0.3f,0.3f,0.3f,1.0f));
ImGui::Button("U", ImVec2(dpadButtonSize, dpadButtonSize));
ImGui::PopStyleColor();
// 左
bool left = Prism::Input::IsGamepadButtonPressed(jid, Prism::GamepadButton::DPAD_LEFT);
ImGui::SetCursorScreenPos(ImVec2(base.x, base.y + dpadButtonSize));
ImGui::PushStyleColor(ImGuiCol_Button, left ? ImVec4(0.0f,1.0f,0.0f,1.0f) : ImVec4(0.3f,0.3f,0.3f,1.0f));
ImGui::Button("L", ImVec2(dpadButtonSize, dpadButtonSize));
ImGui::PopStyleColor();
// 右
bool right = Prism::Input::IsGamepadButtonPressed(jid, Prism::GamepadButton::DPAD_RIGHT);
ImGui::SetCursorScreenPos(ImVec2(base.x + 2*dpadButtonSize, base.y + dpadButtonSize));
ImGui::PushStyleColor(ImGuiCol_Button, right ? ImVec4(0.0f,1.0f,0.0f,1.0f) : ImVec4(0.3f,0.3f,0.3f,1.0f));
ImGui::Button("R", ImVec2(dpadButtonSize, dpadButtonSize));
ImGui::PopStyleColor();
// 下
bool down = Prism::Input::IsGamepadButtonPressed(jid, Prism::GamepadButton::DPAD_DOWN);
ImGui::SetCursorScreenPos(ImVec2(base.x + dpadButtonSize, base.y + 2*dpadButtonSize));
ImGui::PushStyleColor(ImGuiCol_Button, down ? ImVec4(0.0f,1.0f,0.0f,1.0f) : ImVec4(0.3f,0.3f,0.3f,1.0f));
ImGui::Button("D", ImVec2(dpadButtonSize, dpadButtonSize));
ImGui::PopStyleColor();
// 让 Group 大小包含整个十字区域
ImGui::SetCursorScreenPos(ImVec2(base.x, base.y + 3*dpadButtonSize));
ImGui::Dummy(ImVec2(3*dpadButtonSize, 0));
ImGui::EndGroup();
};
// ABXY 按钮组按手柄实际位置排列X左 Y上 B右 A下
auto drawABXY = [&]()
{
ImGui::BeginGroup();
ImGui::Text("Buttons");
ImVec2 base = ImGui::GetCursorScreenPos();
// Y 上
bool y = Prism::Input::IsGamepadButtonPressed(jid, Prism::GamepadButton::Y);
ImGui::SetCursorScreenPos(ImVec2(base.x + buttonSize, base.y));
ImGui::PushStyleColor(ImGuiCol_Button, y ? ImVec4(1.0f,0.8f,0.0f,1.0f) : ImVec4(0.3f,0.3f,0.3f,1.0f));
ImGui::Button("Y", ImVec2(buttonSize, buttonSize));
ImGui::PopStyleColor();
// X 左
bool x = Prism::Input::IsGamepadButtonPressed(jid, Prism::GamepadButton::X);
ImGui::SetCursorScreenPos(ImVec2(base.x, base.y + buttonSize));
ImGui::PushStyleColor(ImGuiCol_Button, x ? ImVec4(0.0f,0.7f,1.0f,1.0f) : ImVec4(0.3f,0.3f,0.3f,1.0f));
ImGui::Button("X", ImVec2(buttonSize, buttonSize));
ImGui::PopStyleColor();
// B 右
bool b = Prism::Input::IsGamepadButtonPressed(jid, Prism::GamepadButton::B);
ImGui::SetCursorScreenPos(ImVec2(base.x + 2*buttonSize, base.y + buttonSize));
ImGui::PushStyleColor(ImGuiCol_Button, b ? ImVec4(1.0f,0.0f,0.0f,1.0f) : ImVec4(0.3f,0.3f,0.3f,1.0f));
ImGui::Button("B", ImVec2(buttonSize, buttonSize));
ImGui::PopStyleColor();
// A 下
bool a = Prism::Input::IsGamepadButtonPressed(jid, Prism::GamepadButton::A);
ImGui::SetCursorScreenPos(ImVec2(base.x + buttonSize, base.y + 2*buttonSize));
ImGui::PushStyleColor(ImGuiCol_Button, a ? ImVec4(0.0f,1.0f,0.0f,1.0f) : ImVec4(0.3f,0.3f,0.3f,1.0f));
ImGui::Button("A", ImVec2(buttonSize, buttonSize));
ImGui::PopStyleColor();
ImGui::SetCursorScreenPos(ImVec2(base.x, base.y + 3*buttonSize));
ImGui::Dummy(ImVec2(3*buttonSize, 0));
ImGui::EndGroup();
};
// 右摇杆区域
auto drawRightStick = [&](float x, float y)
{
y = -y;
ImGui::BeginGroup();
ImGui::Text("R Stick");
ImVec2 pos = ImGui::GetCursorScreenPos();
ImVec2 center(pos.x + stickRadius, pos.y + stickRadius);
drawList->AddCircleFilled(center, stickRadius, IM_COL32(30,30,30,255));
drawList->AddCircle(center, stickRadius, IM_COL32(100,100,100,255), 0, 2.0f);
drawList->AddLine(ImVec2(center.x - stickRadius, center.y), ImVec2(center.x + stickRadius, center.y), IM_COL32(70,70,70,255));
drawList->AddLine(ImVec2(center.x, center.y - stickRadius), ImVec2(center.x, center.y + stickRadius), IM_COL32(70,70,70,255));
float len = sqrtf(x*x + y*y);
float clampX = x, clampY = y;
if (len > 1.0f) { clampX /= len; clampY /= len; }
float dotX = center.x + clampX * stickRadius;
float dotY = center.y - clampY * stickRadius;
drawList->AddCircleFilled(ImVec2(dotX, dotY), 6.0f, IM_COL32(255,80,80,255));
if (len > 0.99f)
drawList->AddCircle(center, stickRadius, IM_COL32(255,255,0,150), 0, 3.0f);
ImGui::Dummy(stickSize);
ImGui::EndGroup();
};
// 获取摇杆当前值
const float lx = Input::GetGamepadAxis(jid, GamepadAxis::LEFT_X);
const float ly = Input::GetGamepadAxis(jid, GamepadAxis::LEFT_Y);
const float rx = Input::GetGamepadAxis(jid, GamepadAxis::RIGHT_X);
const float ry = Input::GetGamepadAxis(jid, GamepadAxis::RIGHT_Y);
// ----- 第一行:左摇杆 | 十字键 | ABXY | 右摇杆 -----
ImGui::BeginGroup();
// 缩进稍微调整
ImGui::Columns(4, "MainControls", false);
ImGui::SetColumnWidth(0, stickSize.x + 10);
ImGui::SetColumnWidth(1, 3*dpadButtonSize + 10);
ImGui::SetColumnWidth(2, 3*buttonSize + 10);
ImGui::SetColumnWidth(3, stickSize.x + 10);
drawStick("L Stick", lx, ly);
ImGui::NextColumn();
drawDPad();
ImGui::NextColumn();
drawABXY();
ImGui::NextColumn();
drawRightStick(rx, ry);
ImGui::Columns(1);
ImGui::EndGroup();
ImGui::Spacing();
// ----- 第二行:肩键 LB/RB 和扳机轴 -----
ImGui::Text("Bumpers & Triggers");
bool lb = Input::IsGamepadButtonPressed(jid, Prism::GamepadButton::LEFT_BUMPER);
bool rb = Input::IsGamepadButtonPressed(jid, Prism::GamepadButton::RIGHT_BUMPER);
float lt = Input::GetGamepadAxis(jid, Prism::GamepadAxis::LEFT_TRIGGER);
float rt = Input::GetGamepadAxis(jid, Prism::GamepadAxis::RIGHT_TRIGGER);
ImGui::BeginGroup();
ImGui::PushStyleColor(ImGuiCol_Button, lb ? ImVec4(0.0f,1.0f,0.0f,1.0f) : ImVec4(0.3f,0.3f,0.3f,1.0f));
ImGui::Button("LB", ImVec2(40, 20));
ImGui::PopStyleColor();
ImGui::SameLine();
ImGui::ProgressBar(lt, ImVec2(100, 20), "");
ImGui::SameLine();
ImGui::Text("LT %.2f", lt);
ImGui::SameLine(0, 30);
ImGui::ProgressBar(rt, ImVec2(100, 20), "");
ImGui::SameLine();
ImGui::Text("RT %.2f", rt);
ImGui::SameLine();
ImGui::PushStyleColor(ImGuiCol_Button, rb ? ImVec4(0.0f,1.0f,0.0f,1.0f) : ImVec4(0.3f,0.3f,0.3f,1.0f));
ImGui::Button("RB", ImVec2(40, 20));
ImGui::PopStyleColor();
ImGui::EndGroup();
ImGui::Spacing();
// ----- 第三行:功能键 Back, Guide, Start, LThumb, RThumb -----
ImGui::Text("Function Keys");
auto drawFuncBtn = [&](const char* label, Prism::GamepadButton btn)
{
bool pressed = Input::IsGamepadButtonPressed(jid, btn);
ImGui::PushStyleColor(ImGuiCol_Button, pressed ? ImVec4(0.0f,1.0f,0.0f,1.0f) : ImVec4(0.3f,0.3f,0.3f,1.0f));
ImGui::Button(label, ImVec2(60, 25));
ImGui::PopStyleColor();
ImGui::SameLine(0, 4);
};
drawFuncBtn("Back", GamepadButton::BACK);
drawFuncBtn("Guide", GamepadButton::GUIDE);
drawFuncBtn("Start", GamepadButton::START);
ImGui::SameLine(0, 20);
drawFuncBtn("LThumb", GamepadButton::LEFT_THUMB);
drawFuncBtn("RThumb", GamepadButton::RIGHT_THUMB);
ImGui::NewLine();
ImGui::TreePop();
}
}
if (!anyConnected)
ImGui::Text("No gamepads connected.");
ImGui::End();
}
std::pair<float, float> EditorLayer::GetMouseViewportSpace() const std::pair<float, float> EditorLayer::GetMouseViewportSpace() const
{ {
auto [mx, my] = ImGui::GetMousePos(); // Input::GetMousePosition(); auto [mx, my] = ImGui::GetMousePos(); // Input::GetMousePosition();
@ -1302,7 +1550,7 @@ namespace Prism
m_SceneState = SceneState::Play; m_SceneState = SceneState::Play;
if (m_ReloadScriptOnPlay) if (m_ReloadScriptOnPlay)
ScriptEngine::ReloadAssembly("assets/scripts/ExampleApp.dll"); ScriptEngine::ReloadAssembly("assets/Scripts/Assembly-CSharp.dll");
m_RuntimeScene = Ref<Scene>::Create(); m_RuntimeScene = Ref<Scene>::Create();
m_EditorScene->CopyTo(m_RuntimeScene); m_EditorScene->CopyTo(m_RuntimeScene);

View File

@ -33,6 +33,10 @@ namespace Prism
void SelectEntity(Entity entity); void SelectEntity(Entity entity);
void UpdateWindowTitle(const std::string& sceneName); void UpdateWindowTitle(const std::string& sceneName);
// GamePad Utils
void DrawGamepadDebugPanel(bool& p_open);
private: private:
std::pair<float, float> GetMouseViewportSpace() const; std::pair<float, float> GetMouseViewportSpace() const;
std::pair<glm::vec3, glm::vec3> CastRay(float mx, float my); std::pair<glm::vec3, glm::vec3> CastRay(float mx, float my);
@ -145,6 +149,7 @@ namespace Prism
bool m_ViewportPanelHovered = false; bool m_ViewportPanelHovered = false;
bool m_ViewportPanelFocused = false; bool m_ViewportPanelFocused = false;
bool m_ShowPhysicsSettings = false; bool m_ShowPhysicsSettings = false;
bool m_ShowGamePadSettings = false;
enum class SceneState enum class SceneState
{ {

View File

@ -454,7 +454,7 @@ void main()
vec3 iblContribution = IBL(F0, Lr) * u_IBLContribution; vec3 iblContribution = IBL(F0, Lr) * u_IBLContribution;
color = vec4(lightContribution + iblContribution, m_Params.Albedo.a); color = vec4(lightContribution + iblContribution, 1.0);
// Bloom // Bloom
float brightness = dot(color.rgb, vec3(0.2126, 0.7152, 0.0722)); float brightness = dot(color.rgb, vec3(0.2126, 0.7152, 0.0722));

Some files were not shown because too many files have changed in this diff Show More