feat: Add "simple" inspector to the imgui panels

This commit is contained in:
2026-08-12 00:59:04 +02:00
parent 662940793e
commit 8c7302de49
26 changed files with 649 additions and 19 deletions
+53 -18
View File
@@ -8,6 +8,7 @@
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/quaternion.hpp>
#include <algorithm>
#include <imgui.h>
#include <optional>
#include <sstream>
@@ -327,24 +328,58 @@ void Animator::Update(float dt) {
}
void Animator::ImGuiInspector() {
// ImGui::Text("Clip: %s", m_currentClipName.empty() ? "(none)" : m_currentClipName.c_str());
// ImGui::Text("Time: %.2f", m_current.time);
// ImGui::Text("Blend: %.2f", m_blendT);
//
// if (!isPlaying()) {
// ImGui::BeginDisabled();
// ImGui::Button("Stop");
// ImGui::EndDisabled();
// } else if (ImGui::Button("Stop")) {
// stop();
// }
//
// ImGui::Separator();
// ImGui::Text("Clips:");
// for (auto& [name, _] : m_clips) {
// if (ImGui::Selectable(name.c_str(), name == m_currentClipName))
// play(name);
// }
if (m_skeletonAsset.empty()) {
ImGui::TextDisabled("Skeleton: <none>");
} else {
ImGui::TextWrapped("Skeleton: %s", m_skeletonAsset.path.c_str());
if (!m_skeletonAsset.subresource.empty()) {
ImGui::TextWrapped(
"Skeleton subresource: %s",
m_skeletonAsset.subresource.c_str());
}
}
ImGui::Text("Joints: %zu", m_skeleton.joints.size());
if (!m_referencesResolved) {
ImGui::TextDisabled("Asset references are waiting to be resolved.");
}
if (m_current.clip == nullptr) {
ImGui::TextDisabled("Playback: stopped");
} else {
ImGui::Text("Playing: %s", m_currentClipName.c_str());
float speed = m_current.speed;
if (ImGui::DragFloat("Playback speed", &speed, 0.05f)) {
m_current.speed = speed;
}
ImGui::Text("Time: %.2f / %.2f s", m_current.time, m_current.clip->duration);
ImGui::Text("Blend: %.2f", m_blendT);
}
const bool wasPlaying = isPlaying();
if (!wasPlaying) {
ImGui::BeginDisabled();
}
if (ImGui::Button("Stop")) {
stop();
}
if (!wasPlaying) {
ImGui::EndDisabled();
}
ImGui::Separator();
ImGui::Text("Clips: %zu", m_clips.size());
for (const std::string& name : m_clipOrder) {
if (!m_clips.contains(name)) {
continue;
}
ImGui::PushID(name.c_str());
if (ImGui::Selectable(name.c_str(), name == m_currentClipName)) {
play(name, 0.15f);
}
ImGui::PopID();
}
}
void Animator::addClip(std::shared_ptr<SkeletalAnimation> clip) {
@@ -8,6 +8,8 @@
#include "destrum/ObjectModel/GameObject.h"
#include "destrum/Util/GameState.h"
#include <imgui.h>
#include <stdexcept>
MeshRendererComponent::MeshRendererComponent(GameObject& parent): Component(parent, "MeshRendererComponent") {
@@ -139,6 +141,30 @@ void MeshRendererComponent::ResolveReferences(const ObjectMap&) {
}
}
void MeshRendererComponent::ImGuiInspector() {
if (meshID == NULL_MESH_ID) {
ImGui::TextDisabled("Mesh: <none>");
} else {
ImGui::Text("Mesh ID: %zu", meshID);
ImGui::TextWrapped(
"Mesh key: %s",
meshKey.empty() ? "<not resolved>" : meshKey.c_str());
}
if (materialID == NULL_MATERIAL_ID) {
ImGui::TextDisabled("Material: <none>");
} else {
ImGui::Text("Material ID: %u", materialID);
ImGui::TextWrapped(
"Material key: %s",
materialKey.empty() ? "<not resolved>" : materialKey.c_str());
}
ImGui::Text(
"Skinning: %s",
m_skinnedMesh != nullptr ? "active" : "static");
}
void MeshRendererComponent::SetMeshID(MeshID id) {
meshID = id;
meshKey.clear();
+66
View File
@@ -9,6 +9,11 @@
#include "destrum/Components/MeshRendererComponent.h"
#include "destrum/Util/GameState.h"
#include "destrum/Util/DeltaTime.h"
#include "destrum/Util/ImGuiUtils.h"
#include <imgui.h>
#include <algorithm>
static glm::vec3 RandomUnitVector(std::mt19937& rng)
{
@@ -175,3 +180,64 @@ void OrbitAndSpin::Deserialize(const nlohmann::json& data) {
}
BuildOrbitBasis();
}
void OrbitAndSpin::ImGuiInspector() {
float radius = m_Radius;
if (ImGui::DragFloat("Radius", &radius, 0.05f, 0.0f)) {
SetRadius(radius);
}
glm::vec3 center = m_Center;
if (ImGuiUtils::DrawVec3Control("Center", center)) {
SetCenter(center);
}
glm::vec3 orbitAxis = m_OrbitAxis;
if (ImGuiUtils::DrawVec3Control("Orbit axis", orbitAxis)) {
if (glm::dot(orbitAxis, orbitAxis) >= 1e-8f) {
m_OrbitAxis = glm::normalize(orbitAxis);
BuildOrbitBasis();
}
}
float orbitSpeed = m_OrbitSpeed;
if (ImGui::DragFloat("Orbit speed", &orbitSpeed, 0.05f)) {
m_OrbitSpeed = orbitSpeed;
}
ImGui::DragFloat("Orbit phase", &m_OrbitPhase, 0.05f);
ImGui::Text("Orbit angle: %.2f rad", m_OrbitAngle);
float growSpeed = m_GrowSpeed;
if (ImGui::DragFloat("Grow speed", &growSpeed, 0.05f, 0.0f)) {
m_GrowSpeed = growSpeed;
}
float growMin = m_GrowMin;
if (ImGui::DragFloat("Grow min", &growMin, 0.01f, 0.0f)) {
m_GrowMin = std::min(growMin, m_GrowMax);
}
float growMax = m_GrowMax;
if (ImGui::DragFloat("Grow max", &growMax, 0.01f, 0.0f)) {
m_GrowMax = std::max(growMax, m_GrowMin);
}
glm::vec3 baseScale = m_BaseScale;
if (ImGuiUtils::DrawVec3Control("Base scale", baseScale, 0.05f)) {
m_BaseScale = baseScale;
}
glm::vec3 spinAxis = m_SpinAxis;
if (ImGuiUtils::DrawVec3Control("Spin axis", spinAxis)) {
if (glm::dot(spinAxis, spinAxis) >= 1e-8f) {
m_SpinAxis = glm::normalize(spinAxis);
}
}
float spinSpeed = m_SpinSpeed;
if (ImGui::DragFloat("Spin speed", &spinSpeed, 0.05f)) {
m_SpinSpeed = spinSpeed;
}
ImGui::Text("Grow phase: %.2f rad", m_GrowPhase);
ImGui::Text("Material ID: %u", m_MaterialID);
}
@@ -1,5 +1,9 @@
#include <destrum/Components/Physics/BoxCollider.h>
#include <destrum/Util/ImGuiUtils.h>
#include <imgui.h>
nlohmann::json BoxCollider::Serialize() const {
auto data = SerializeCollider();
data["halfExtents"] = {m_HalfExtents.x, m_HalfExtents.y, m_HalfExtents.z};
@@ -17,3 +21,12 @@ void BoxCollider::Deserialize(const nlohmann::json& data) {
});
}
}
void BoxCollider::ImGuiInspector() {
Collider::ImGuiInspector();
glm::vec3 halfExtents = m_HalfExtents;
if (ImGuiUtils::DrawVec3Control("Half extents", halfExtents)) {
SetHalfExtents(halfExtents);
}
}
@@ -0,0 +1,17 @@
#include <destrum/Components/Physics/CapsuleCollider.h>
#include <imgui.h>
void CapsuleCollider::ImGuiInspector() {
Collider::ImGuiInspector();
float radius = m_Radius;
if (ImGui::DragFloat("Radius", &radius, 0.05f, 0.0001f)) {
SetRadius(radius);
}
float height = m_Height;
if (ImGui::DragFloat("Height", &height, 0.05f, 0.0001f)) {
SetHeight(height);
}
}
@@ -0,0 +1,17 @@
#include <destrum/Components/Physics/Collider.h>
#include <imgui.h>
#include <destrum/Util/ImGuiUtils.h>
void Collider::ImGuiInspector() {
bool isTrigger = m_IsTrigger;
if (ImGui::Checkbox("Is trigger", &isTrigger)) {
SetTrigger(isTrigger);
}
glm::vec3 centerOffset = m_CenterOffset;
if (ImGuiUtils::DrawVec3Control("Center offset", centerOffset)) {
SetCenterOffset(centerOffset);
}
}
@@ -4,6 +4,8 @@
#include <destrum/ObjectModel/GameObject.h>
#include <destrum/Scene/Scene.h>
#include <imgui.h>
namespace {
[[nodiscard]] const char* RigidbodyTypeName(RigidbodyType type) {
switch (type) {
@@ -128,3 +130,48 @@ void Rigidbody::Deserialize(const nlohmann::json& data) {
m_AllowSleep = data.at("allowSleep").get<bool>();
}
}
void Rigidbody::ImGuiInspector() {
static const char* typeNames[] = {"Static", "Dynamic", "Kinematic"};
int type = static_cast<int>(m_Type);
if (ImGui::Combo("Body type", &type, typeNames, IM_ARRAYSIZE(typeNames))) {
SetType(static_cast<RigidbodyType>(type));
}
float mass = m_Mass;
if (ImGui::DragFloat("Mass", &mass, 0.1f, 0.0001f)) {
SetMass(mass);
}
float friction = m_Friction;
if (ImGui::DragFloat("Friction", &friction, 0.01f, 0.0f)) {
SetFriction(friction);
}
float restitution = m_Restitution;
if (ImGui::SliderFloat("Restitution", &restitution, 0.0f, 1.0f)) {
SetRestitution(restitution);
}
bool useGravity = m_UseGravity;
if (ImGui::Checkbox("Use gravity", &useGravity)) {
SetUseGravity(useGravity);
}
bool allowSleep = m_AllowSleep;
if (ImGui::Checkbox("Allow sleep", &allowSleep)) {
SetAllowSleep(allowSleep);
}
if (HasPhysicsBody()) {
const glm::vec3 velocity = GetLinearVelocity();
ImGui::Text(
"Linear velocity: %.2f, %.2f, %.2f",
velocity.x,
velocity.y,
velocity.z);
ImGui::Text("Physics body: %u", m_Body.id);
} else {
ImGui::TextDisabled("Physics body: not registered");
}
}
@@ -1,5 +1,7 @@
#include <destrum/Components/Physics/SphereCollider.h>
#include <imgui.h>
nlohmann::json SphereCollider::Serialize() const {
auto data = SerializeCollider();
data["radius"] = m_Radius;
@@ -12,3 +14,12 @@ void SphereCollider::Deserialize(const nlohmann::json& data) {
SetRadius(data.at("radius").get<float>());
}
}
void SphereCollider::ImGuiInspector() {
Collider::ImGuiInspector();
float radius = m_Radius;
if (ImGui::DragFloat("Radius", &radius, 0.05f, 0.0001f)) {
SetRadius(radius);
}
}
+27
View File
@@ -6,6 +6,9 @@
#include <glm/gtc/quaternion.hpp> // glm::quat, glm::angleAxis
#include <glm/gtx/quaternion.hpp> // operator*(quat, vec3)
#include <destrum/Util/DeltaTime.h>
#include <destrum/Util/ImGuiUtils.h>
#include <imgui.h>
glm::vec3 Rotator::MakePerpendicularUnitVector(const glm::vec3& axis)
{
@@ -128,3 +131,27 @@ void Rotator::Deserialize(const nlohmann::json& data) {
m_InitialOffset = {value.at(0).get<float>(), value.at(1).get<float>(), value.at(2).get<float>()};
}
}
void Rotator::ImGuiInspector() {
float distance = m_Distance;
if (ImGui::DragFloat("Distance", &distance, 0.05f, 0.0f)) {
SetDistance(distance);
}
float speed = m_Speed;
if (ImGui::DragFloat("Speed", &speed, 0.05f)) {
SetSpeed(speed);
}
glm::vec3 pivot = m_Pivot;
if (ImGuiUtils::DrawVec3Control("Pivot", pivot)) {
SetPivotPosition(pivot);
}
glm::vec3 axis = m_Axis;
if (ImGuiUtils::DrawVec3Control("Axis", axis)) {
SetAxis(axis);
}
ImGui::Text("Current angle: %.2f rad", m_CurrentAngle);
}
+17
View File
@@ -4,6 +4,9 @@
#include "destrum/ObjectModel/Transform.h"
#include "destrum/Util/DeltaTime.h"
#include "destrum/Util/ImGuiUtils.h"
#include <imgui.h>
void Spinner::Update(float dt)
{
@@ -33,3 +36,17 @@ void Spinner::Deserialize(const nlohmann::json& data) {
m_Angle = data.at("angle").get<float>();
}
}
void Spinner::ImGuiInspector() {
glm::vec3 axis = m_Axis;
if (ImGuiUtils::DrawVec3Control("Axis", axis)) {
SetAxis(axis);
}
float speed = m_Speed;
if (ImGui::DragFloat("Speed", &speed, 0.05f)) {
SetSpeed(speed);
}
ImGui::Text("Current angle: %.2f rad", m_Angle);
}