Minor - Improves scene editor and adds audio support - V13.1.0
Improves the scene editor by adding an inspector window to view and modify entity components. Adds audio component support with basic playback controls integrated into the inspector. Adds default audio files.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#include <memory>
|
||||
#include <typeindex>
|
||||
#include <typeinfo>
|
||||
#include <imgui.h>
|
||||
|
||||
/**
|
||||
* namespace for the Entity-Component-System (ECS)
|
||||
@@ -45,6 +46,12 @@ public:
|
||||
* @return True if deserialization was successful, otherwise false.
|
||||
*/
|
||||
virtual bool Deserialize(const std::string& data) { return false;}
|
||||
|
||||
/**
|
||||
* Virtual function to render ImGui controls for the component.
|
||||
* This can be overridden by derived components to provide custom UI.
|
||||
*/
|
||||
virtual void OnImGuiRender() { /* Default implementation does nothing */ }
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// AudioComponent.h
|
||||
#pragma once
|
||||
#include "ecs/component.h"
|
||||
#include "../component.h"
|
||||
#include <Fmod/core/inc/fmod.hpp>
|
||||
#include <string>
|
||||
#include <filesystem>
|
||||
|
||||
namespace ecs {
|
||||
class AudioComponent : public Component {
|
||||
@@ -10,11 +11,59 @@ public:
|
||||
AudioComponent() : m_system(nullptr), m_sound(nullptr), m_channel(nullptr) {}
|
||||
~AudioComponent() override {
|
||||
if (m_sound) m_sound->release();
|
||||
// Ne pas lib<69>rer m_system ici car il peut <20>tre partag<61>
|
||||
}
|
||||
|
||||
bool Load(FMOD::System* system, const std::string& path) {
|
||||
m_system = system;
|
||||
return m_system->createSound(path.c_str(), FMOD_DEFAULT, nullptr, &m_sound) == FMOD_OK;
|
||||
void Initialize() override
|
||||
{
|
||||
// create FMOD system if not already created
|
||||
if (!m_system)
|
||||
{
|
||||
FMOD_RESULT result = FMOD::System_Create(&m_system);
|
||||
if (result != FMOD_OK) {
|
||||
m_lastError = "<EFBFBD>chec de la cr<63>ation du syst<73>me FMOD: " + std::to_string(result);
|
||||
return;
|
||||
}
|
||||
|
||||
result = m_system->init(512, FMOD_INIT_NORMAL, nullptr);
|
||||
if (result != FMOD_OK) {
|
||||
m_lastError = "<EFBFBD>chec de l'initialisation du syst<73>me FMOD: " + std::to_string(result);
|
||||
m_system->release();
|
||||
m_system = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Load(const std::string& path) {
|
||||
if (!m_system) {
|
||||
Initialize();
|
||||
if (!m_system) return false; // L'erreur est d<>j<EFBFBD> d<>finie dans Initialize()
|
||||
}
|
||||
|
||||
m_soundPath = path;
|
||||
|
||||
// V<>rifier si le fichier existe
|
||||
if (!std::filesystem::exists(path)) {
|
||||
m_lastError = "Fichier non trouv<75>: " + path;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Lib<69>rer le son pr<70>c<EFBFBD>dent s'il existe
|
||||
if (m_sound) {
|
||||
m_sound->release();
|
||||
m_sound = nullptr;
|
||||
}
|
||||
|
||||
// Essayer de charger avec le chemin absolu
|
||||
std::filesystem::path absolutePath = std::filesystem::absolute(path);
|
||||
FMOD_RESULT result = m_system->createSound(absolutePath.string().c_str(), FMOD_DEFAULT, nullptr, &m_sound);
|
||||
if (result != FMOD_OK) {
|
||||
m_lastError = "<EFBFBD>chec du chargement du son: " + std::to_string(result) +
|
||||
" (chemin: " + absolutePath.string() + ")";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Play() {
|
||||
@@ -27,9 +76,44 @@ public:
|
||||
m_channel->stop();
|
||||
}
|
||||
|
||||
void OnImGuiRender() override {
|
||||
// Afficher le r<>pertoire de travail actuel
|
||||
std::string currentDir = std::filesystem::current_path().string();
|
||||
ImGui::Text("R<EFBFBD>pertoire actuel: %s", currentDir.c_str());
|
||||
|
||||
if (m_sound) {
|
||||
ImGui::Text("Son charg<72>: %s", m_soundPath.c_str());
|
||||
if (ImGui::Button("Jouer")) {
|
||||
Play();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Arr<EFBFBD>ter")) {
|
||||
Stop();
|
||||
}
|
||||
} else {
|
||||
ImGui::Text("Aucun son charg<72>");
|
||||
|
||||
// Montrer l'erreur s'il y en a une
|
||||
if (!m_lastError.empty()) {
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.0f, 0.0f, 1.0f), "Erreur: %s", m_lastError.c_str());
|
||||
}
|
||||
|
||||
static char path[256] = "F:/Github_Repo/khaotic-engine-Reborn/x64/Release/assets/sounds/default.mp3";
|
||||
ImGui::InputText("Chemin du fichier", path, sizeof(path));
|
||||
|
||||
if (ImGui::Button("Charger le son")) {
|
||||
if (!Load(path)) {
|
||||
// L'erreur est d<>j<EFBFBD> d<>finie dans Load()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
FMOD::System* m_system;
|
||||
FMOD::Sound* m_sound;
|
||||
FMOD::Channel* m_channel;
|
||||
std::string m_soundPath;
|
||||
std::string m_lastError;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -134,6 +134,20 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnImGuiRender() override {
|
||||
ImGui::Text("ID: %d", m_id);
|
||||
char nameBuffer[256];
|
||||
strncpy_s(nameBuffer, m_name.c_str(), sizeof(nameBuffer));
|
||||
if (ImGui::InputText("#Name", nameBuffer, sizeof(nameBuffer))) {
|
||||
m_name = std::string(nameBuffer);
|
||||
}
|
||||
|
||||
const char* objectTypes[] = { "Unknown", "Cube", "Sphere", "Terrain" };
|
||||
int currentTypeIndex = static_cast<int>(m_type);
|
||||
if (ImGui::Combo("Object Type", ¤tTypeIndex, objectTypes, IM_ARRAYSIZE(objectTypes))) {
|
||||
m_type = static_cast<ObjectType>(currentTypeIndex);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
int m_id; // ID unique de l'objet
|
||||
|
||||
@@ -55,6 +55,16 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnImGuiRender() override {
|
||||
char path[260];
|
||||
std::string currentPath = convert_w_string_to_string(m_path);
|
||||
strcpy_s(path, currentPath.c_str());
|
||||
|
||||
if (ImGui::InputText("Model Path", path, sizeof(path))) {
|
||||
SetPath(std::wstring(path, path + strlen(path)));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::wstring m_path;
|
||||
};
|
||||
|
||||
@@ -233,6 +233,45 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnImGuiRender() override {
|
||||
float mass = GetMass();
|
||||
if (ImGui::DragFloat("Mass", &mass, 0.1f, 0.1f, 100.0f)) {
|
||||
SetMass(mass);
|
||||
}
|
||||
|
||||
float radius = GetBoundingRadius();
|
||||
if (ImGui::DragFloat("Bounding Radius", &radius, 0.1f, 0.1f, 100.0f)) {
|
||||
SetBoundingRadius(radius);
|
||||
}
|
||||
|
||||
bool physicsEnabled = IsPhysicsEnabled();
|
||||
if (ImGui::Checkbox("Physics Enabled", &physicsEnabled)) {
|
||||
SetPhysicsEnabled(physicsEnabled);
|
||||
}
|
||||
|
||||
bool gravityEnabled = IsGravityEnabled();
|
||||
if (ImGui::Checkbox("Gravity Enabled", &gravityEnabled)) {
|
||||
SetGravityEnabled(gravityEnabled);
|
||||
}
|
||||
|
||||
bool isGrounded = IsGrounded();
|
||||
if (ImGui::Checkbox("Is Grounded", &isGrounded)) {
|
||||
SetGrounded(isGrounded);
|
||||
}
|
||||
|
||||
XMFLOAT3 velocity;
|
||||
XMStoreFloat3(&velocity, GetVelocity());
|
||||
if (ImGui::DragFloat3("Velocity", &velocity.x, 0.1f)) {
|
||||
SetVelocity(XMLoadFloat3(&velocity));
|
||||
}
|
||||
|
||||
XMFLOAT3 acceleration;
|
||||
XMStoreFloat3(&acceleration, GetAcceleration());
|
||||
if (ImGui::DragFloat3("Acceleration", &acceleration.x, 0.1f)) {
|
||||
SetAcceleration(XMLoadFloat3(&acceleration));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
XMVECTOR m_Velocity;
|
||||
XMVECTOR m_Acceleration;
|
||||
|
||||
@@ -208,6 +208,16 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnImGuiRender() override {
|
||||
ImGui::Checkbox("Visible", &m_isVisible);
|
||||
ImGui::Text("Model File Path: %s", m_modelFilePath.c_str());
|
||||
if (m_model) {
|
||||
ImGui::Text("Index Count: %d", m_model->GetIndexCount());
|
||||
} else {
|
||||
ImGui::Text("No model loaded.");
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<model_class> m_model;
|
||||
std::string m_modelFilePath;
|
||||
|
||||
@@ -110,6 +110,27 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnImGuiRender() override {
|
||||
ShaderType currentShader = GetActiveShader();
|
||||
int shaderIndex = static_cast<int>(currentShader);
|
||||
const char* shaderNames[] = {
|
||||
"CEL_SHADING",
|
||||
"LIGHTING",
|
||||
"NORMAL_MAPPING",
|
||||
"SPECULAR_MAPPING",
|
||||
"REFLECTION",
|
||||
"REFRACTION",
|
||||
"TEXTURE",
|
||||
"SKYBOX",
|
||||
"SUNLIGHT",
|
||||
"ALPHA_MAPPING"
|
||||
};
|
||||
|
||||
if (ImGui::Combo("Active Shader", &shaderIndex, shaderNames, IM_ARRAYSIZE(shaderNames))) {
|
||||
SetActiveShader(static_cast<ShaderType>(shaderIndex));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
ShaderType m_activeShader;
|
||||
};
|
||||
|
||||
@@ -197,6 +197,26 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnImGuiRender() override {
|
||||
XMFLOAT3 position, rotation, scale;
|
||||
XMStoreFloat3(&position, GetPosition());
|
||||
XMStoreFloat3(&rotation, GetRotation());
|
||||
XMStoreFloat3(&scale, GetScale());
|
||||
|
||||
if (ImGui::DragFloat3("Position", &position.x, 0.1f)) {
|
||||
SetPosition(XMLoadFloat3(&position));
|
||||
}
|
||||
|
||||
if (ImGui::DragFloat3("Rotation", &rotation.x, 0.01f)) {
|
||||
SetRotation(XMLoadFloat3(&rotation));
|
||||
}
|
||||
|
||||
if (ImGui::DragFloat3("Scale", &scale.x, 0.1f, 0.01f, 100.0f)) {
|
||||
SetScale(XMLoadFloat3(&scale));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
XMMATRIX m_ScaleMatrix;
|
||||
XMMATRIX m_RotateMatrix;
|
||||
|
||||
@@ -128,6 +128,22 @@ public:
|
||||
m_NextEntityID = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get entity by ID (const version).
|
||||
* @param id The ID of the entity to retrieve.
|
||||
* @return A shared pointer to the entity, or nullptr if it does not exist.
|
||||
*/
|
||||
std::shared_ptr<Entity> GetEntityByID(EntityID entityID)
|
||||
{
|
||||
if (entityID < m_Entities.size())
|
||||
{
|
||||
return m_Entities[entityID];
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
EntityID m_NextEntityID;
|
||||
std::unordered_map<EntityID, std::shared_ptr<Entity>> m_Entities;
|
||||
|
||||
Reference in New Issue
Block a user